Java中的数组复制
给定一个数组,我们需要将其元素复制到一个不同的数组中,对于一个天真的用户来说,下面的方式会出现,但这是不正确的,如下所示:
// Java Program to Illustrate Wrong Way Of Copying an Array
// Input array
int a[] = { 1, 8, 3 };
// Creating an array b[] of same size as a[]
int b[] = new int[a.length];
// Doesn't copy elements of a[] to b[], only makes
// b refer to same location
b = a;
输出:
输出说明:当我们执行“b = a”时,我们实际上是在为数组分配一个引用。因此,如果我们对一个数组进行任何更改,它也会反映在其他数组中,因为 a 和 b 都指向同一个位置。我们也可以通过如下代码验证:
例子:
Java
// A Java program to demonstrate that simply
// assigning one array reference is incorrect
public class Test {
public static void main(String[] args)
{
int a[] = { 1, 8, 3 };
// Create an array b[] of same size as a[]
int b[] = new int[a.length];
// Doesn't copy elements of a[] to b[],
// only makes b refer to same location
b = a;
// Change to b[] will also reflect in a[]
// as 'a' and 'b' refer to same location.
b[0]++;
System.out.println("Contents of a[] ");
for (int i = 0; i < a.length; i++)
System.out.print(a[i] + " ");
System.out.println("\n\nContents of b[] ");
for (int i = 0; i < b.length; i++)
System.out.print(b[i] + " ");
}
}
Java
// Java program to demonstrate copying by
// one by one assigning elements between arrays
// Main class
public class GFG {
// Main driver method
public static void main(String[] args)
{
// Input array a[]
int a[] = { 1, 8, 3 };
// Create an array b[] of same size as a[]
int b[] = new int[a.length];
// Copying elements of a[] to b[]
for (int i = 0; i < a.length; i++)
b[i] = a[i];
// Changing b[] to verify that
// b[] is different from a[]
b[0]++;
// Display message only
System.out.println("Contents of a[] ");
for (int i = 0; i < a.length; i++)
System.out.print(a[i] + " ");
// Display message only
System.out.println("\n\nContents of b[] ");
for (int i = 0; i < b.length; i++)
System.out.print(b[i] + " ");
}
}
Java
// Java program to demonstrate Copying of Array
// using clone() method
// Main class
public class GFG {
// Main driver method
public static void main(String[] args)
{
// Input array a[]
int a[] = { 1, 8, 3 };
// Copying elements of a[] to b[]
int b[] = a.clone();
// Changing b[] to verify that
// b[] is different from a[]
b[0]++;
// Display message for better readability
System.out.println("Contents of a[] ");
for (int i = 0; i < a.length; i++)
System.out.print(a[i] + " ");
// Display message for better readability
System.out.println("\n\nContents of b[] ");
for (int i = 0; i < b.length; i++)
System.out.print(b[i] + " ");
}
}
Java
// Java program to demonstrate array
// copy using System.arraycopy()
// Main class
public class GFG {
// Main driver method
public static void main(String[] args)
{
// Custom input array
int a[] = { 1, 8, 3 };
// Creating an array b[] of same size as a[]
int b[] = new int[a.length];
// Copying elements of a[] to b[]
System.arraycopy(a, 0, b, 0, 3);
// Changing b[] to verify that
// b[] is different from a[]
b[0]++;
// Display message only
System.out.println("Contents of a[] ");
for (int i = 0; i < a.length; i++)
System.out.print(a[i] + " ");
// Display message only
System.out.println("\n\nContents of b[] ");
for (int i = 0; i < b.length; i++)
System.out.print(b[i] + " ");
}
}
Java
// Java program to demonstrate array
// copy using Arrays.copyOf()
// Importing Arrays class from utility class
import java.util.Arrays;
// Main class
class GFG {
// Main driver method
public static void main(String[] args)
{
// Custom input array
int a[] = { 1, 8, 3 };
// Create an array b[] of same size as a[]
// Copy elements of a[] to b[]
int b[] = Arrays.copyOf(a, 3);
// Change b[] to verify that
// b[] is different from a[]
b[0]++;
System.out.println("Contents of a[] ");
// Iterating over array. a[]
for (int i = 0; i < a.length; i++)
System.out.print(a[i] + " ");
System.out.println("\n\nContents of b[] ");
// Iterating over array b[]
for (int i = 0; i < b.length; i++)
System.out.print(b[i] + " ");
}
}
Java
// Java program to demonstrate array
// copy using Arrays.copyOfRange()
// Importing Arrays class from utility package
import java.util.Arrays;
// Main class
class GFG {
// Main driver method
public static void main(String[] args)
{
// Custom input array
int a[] = { 1, 8, 3, 5, 9, 10 };
// Creating an array b[] and
// copying elements of a[] to b[]
int b[] = Arrays.copyOfRange(a, 2, 6);
// Changing b[] to verify that
// b[] is different from a[]
// Iterating over array a[]
System.out.println("Contents of a[] ");
for (int i = 0; i < a.length; i++)
System.out.print(a[i] + " ");
// Iterating over array b[]
System.out.println("\n\nContents of b[] ");
for (int i = 0; i < b.length; i++)
System.out.print(b[i] + " ");
}
}
输出
Contents of a[]
2 8 3
Contents of b[]
2 8 3
方法:
我们已经看到了复制元素时的内部工作以及在遇到上述错误后要考虑的边缘情况,因此现在我们可以提出正确的复制数组的方法,如下所示:
- 迭代给定原始数组的每个元素并一次复制一个元素
- 使用 clone() 方法
- 使用 arraycopy() 方法
- 使用 Arrays 类的 copyOf() 方法
- 使用 Arrays 类的 copyOfRange() 方法
方法1:迭代给定原始数组的每个元素,一次复制一个元素。使用该方法可以保证对 b 的任何修改,都不会改变原来的数组 a,如下例所示:
例子:
Java
// Java program to demonstrate copying by
// one by one assigning elements between arrays
// Main class
public class GFG {
// Main driver method
public static void main(String[] args)
{
// Input array a[]
int a[] = { 1, 8, 3 };
// Create an array b[] of same size as a[]
int b[] = new int[a.length];
// Copying elements of a[] to b[]
for (int i = 0; i < a.length; i++)
b[i] = a[i];
// Changing b[] to verify that
// b[] is different from a[]
b[0]++;
// Display message only
System.out.println("Contents of a[] ");
for (int i = 0; i < a.length; i++)
System.out.print(a[i] + " ");
// Display message only
System.out.println("\n\nContents of b[] ");
for (int i = 0; i < b.length; i++)
System.out.print(b[i] + " ");
}
}
输出
Contents of a[]
1 8 3
Contents of b[]
2 8 3
方法二:使用 Clone() 方法
在之前的方法中,我们必须遍历整个数组来制作副本,我们能做得更好吗?是的,我们可以在Java中使用 clone 方法。
例子:
Java
// Java program to demonstrate Copying of Array
// using clone() method
// Main class
public class GFG {
// Main driver method
public static void main(String[] args)
{
// Input array a[]
int a[] = { 1, 8, 3 };
// Copying elements of a[] to b[]
int b[] = a.clone();
// Changing b[] to verify that
// b[] is different from a[]
b[0]++;
// Display message for better readability
System.out.println("Contents of a[] ");
for (int i = 0; i < a.length; i++)
System.out.print(a[i] + " ");
// Display message for better readability
System.out.println("\n\nContents of b[] ");
for (int i = 0; i < b.length; i++)
System.out.print(b[i] + " ");
}
}
输出
Contents of a[]
1 8 3
Contents of b[]
2 8 3
方法 3:使用 arraycopy() 方法
我们也可以使用System.arraycopy()方法。该系统存在于Java.lang 包中。它的签名如下:
public static void arraycopy(Object src, int srcPos, Object dest,
int destPos, int length)
参数:
- src表示源数组。
- srcPos是复制开始的索引。
- dest表示目标数组
- destPos是复制元素放置在目标数组中的索引。
- length是要复制的子数组的长度。
例子:
Java
// Java program to demonstrate array
// copy using System.arraycopy()
// Main class
public class GFG {
// Main driver method
public static void main(String[] args)
{
// Custom input array
int a[] = { 1, 8, 3 };
// Creating an array b[] of same size as a[]
int b[] = new int[a.length];
// Copying elements of a[] to b[]
System.arraycopy(a, 0, b, 0, 3);
// Changing b[] to verify that
// b[] is different from a[]
b[0]++;
// Display message only
System.out.println("Contents of a[] ");
for (int i = 0; i < a.length; i++)
System.out.print(a[i] + " ");
// Display message only
System.out.println("\n\nContents of b[] ");
for (int i = 0; i < b.length; i++)
System.out.print(b[i] + " ");
}
}
输出
Contents of a[]
1 8 3
Contents of b[]
2 8 3
方法四:使用Arrays类的copyOf()方法
如果我们想复制数组的前几个元素或数组的完整副本,可以使用这种方法。
句法:
public static int[] copyOf(int[] original, int newLength)
参数:
- 原始数组
- 要复制的数组的长度。
例子:
Java
// Java program to demonstrate array
// copy using Arrays.copyOf()
// Importing Arrays class from utility class
import java.util.Arrays;
// Main class
class GFG {
// Main driver method
public static void main(String[] args)
{
// Custom input array
int a[] = { 1, 8, 3 };
// Create an array b[] of same size as a[]
// Copy elements of a[] to b[]
int b[] = Arrays.copyOf(a, 3);
// Change b[] to verify that
// b[] is different from a[]
b[0]++;
System.out.println("Contents of a[] ");
// Iterating over array. a[]
for (int i = 0; i < a.length; i++)
System.out.print(a[i] + " ");
System.out.println("\n\nContents of b[] ");
// Iterating over array b[]
for (int i = 0; i < b.length; i++)
System.out.print(b[i] + " ");
}
}
输出
Contents of a[]
1 8 3
Contents of b[]
2 8 3
方法5:使用Arrays类的copyOfRange()方法
此方法将指定数组的指定范围复制到一个新数组中。
public static int[] copyOfRange(int[] original, int from, int to)
参数:
- 要从中复制范围的原始数组
- 要复制的范围的初始索引
- 要复制的范围的最终索引,不包括
例子:
Java
// Java program to demonstrate array
// copy using Arrays.copyOfRange()
// Importing Arrays class from utility package
import java.util.Arrays;
// Main class
class GFG {
// Main driver method
public static void main(String[] args)
{
// Custom input array
int a[] = { 1, 8, 3, 5, 9, 10 };
// Creating an array b[] and
// copying elements of a[] to b[]
int b[] = Arrays.copyOfRange(a, 2, 6);
// Changing b[] to verify that
// b[] is different from a[]
// Iterating over array a[]
System.out.println("Contents of a[] ");
for (int i = 0; i < a.length; i++)
System.out.print(a[i] + " ");
// Iterating over array b[]
System.out.println("\n\nContents of b[] ");
for (int i = 0; i < b.length; i++)
System.out.print(b[i] + " ");
}
}
输出
Contents of a[]
1 8 3 5 9 10
Contents of b[]
3 5 9 10
最后,让我们讨论一下上述方法的概述:
- 简单地分配引用是错误的
- 可以通过遍历数组来复制数组,并一一分配元素。
- 我们可以避免使用 clone() 或 System.arraycopy()对元素进行迭代
- clone() 创建一个相同大小的新数组,但System.arraycopy()可用于从源范围复制到目标范围。
- System.arraycopy() 比 clone() 更快,因为它使用Java Native Interface
- 如果要复制数组的前几个元素或数组的完整副本,可以使用 Arrays.copyOf() 方法。
- Arrays.copyOfRange() 用于复制数组的指定范围。如果起始索引不为 0,则可以使用此方法复制部分数组。