在本文,我们将讨论Java数组的复制操作。Java提供了各种方法来复制数组元素。众所周知,在Java中,数组可以包含原始类型或对象或引用的元素。
在制作原始类型的副本时,任务相当容易,但是当涉及对象或引用时,您需要注意副本是深副本还是浅副本。
浅拷贝将复制元素。当涉及原始数据类型时,这不是问题。但是,当涉及到引用时,浅表副本将仅复制值而不是基础信息。
因此,即使您已经复制了元素,但是在共享存储位置时,一个副本中的更改也会反映在其他副本中。为避免这种情况,您需要进行深拷贝,其中不共享内存位置。
复制和克隆Java数组
Java允许您使用java.util或System类提供的直接复制方法来复制数组。它还提供了用于克隆整个阵列的克隆方法。
在本教程中,我们将讨论以下复制和克隆数组的方法。
- 使用for循环手动复制
- 使用System.arraycopy()
- 使用Arrays.copyOf()
- 使用Arrays.copyOfRange()
- 使用Object.clone()
让我们探索!!
使用For循环手动复制
通常,当我们复制变量(例如a和b)时,我们将执行以下复制操作:
a = b;
如果我们对数组应用相同的方法,它将无法正常工作。
让我们看一个编程示例。
public class Main
{
public static void main(String[] args)
{
int intArray[] = { 12 , 15 , 17 };
//print original intArray
System.out.println( "Contents of intArray[] before assignment:" );
for ( int i= 0 ; i<intArray.length; i++)
System.out.print(intArray[i] + " " );
// Create an array b[] of same size as a[]
int copyArray[] = new int [intArray.length];
// intArray is assigned to copyArray; so references point to same location
copyArray = intArray;
// change element of copyArray
copyArray[ 1 ]++;
//print both arrays
System.out.println( "\nContents of intArray[]:" );
for ( int i= 0 ; i<intArray.length; i++)
System.out.print(intArray[i] + " " );
System.out.println( "\nContents of copyArray[]:" );
for ( int i= 0 ; i<copyArray.length; i++)
System.out.print(copyArray[i] + " " );
}
}
|
输出:
在上面的程序中,有两个数组,即intArray和copyArray。任务是将intArray的内容复制到copyArray。为此,引入了copyArray = intArray语句。此处完成的工作是分配数组的引用。因此,这不是实际的复制。
由于上述声明,intArray的内存位置也由copyArray共享。现在,当copyArray元素增加时,该更改也将反映在intArray中。这在输出中显示。
为了克服这个问题,我们采用了一种使用for循环复制数组的方法。在这里,使用for循环将原始数组的每个元素复制到新数组。
该程序如下所示。
public class Main
{
public static void main(String[] args)
{
int intArray[] = { 12 , 15 , 17 };
// define an array copyArray to copy contents of intArray
int copyArray[] = new int [intArray.length];
// copy contents of intArray to copyArray
for ( int i= 0 ; i<intArray.length; i++)
copyArray[i] = intArray[i];
// update element of copyArray
copyArray[ 0 ]++;
//print both arrays
System.out.println( "intArray[] elements:" );
for ( int i= 0 ; i<intArray.length; i++)
System.out.print(intArray[i] + " " );
System.out.println( "\n\ncopyArray[] elements:" );
for ( int i= 0 ; i<copyArray.length; i++)
System.out.print(copyArray[i] + " " );
}
}
|
输出:
在这里,我们修改了先前的程序,使其包含for循环和内部for循环,我们将intArray的每个元素分配给copyArray的相应元素。这样,元素实际上就被复制了。因此,当修改一个数组时,更改不会反映在另一个数组中。
使用System.arraycopy()
Java的System类具有一个称为“ ArrayCOpy”的方法,该方法使您可以将一个数组的元素复制到另一个数组。
此方法的一般原型如下:
public static void arraycopy(
Object src_array, int src_Pos,Object dest_array, int dest_Pos, int length )
|
这里,
- src_array =>要从中复制内容的源数组。
- src_Pos =>复制开始的源数组中的位置。
- dest_array =>要将元素复制到的目标数组。
- dest_Pos =>要复制的元素在目标数组中的起始位置。
- length =>要复制的数组的长度。
让我们通过一个例子来理解这种方法。
class Main {
public static void main(String[] args) {
//declaring a source array
char [] src_array = { 'S' , 'o' , 'f' , 't' , 'w' , 'a' , 'r' , 'e' , 'T' , 'e' , 's' , 't' , 'i' , 'n' , 'g' , 'H' , 'e' , 'l' , 'p' };
char [] dest_array = new char [ 19 ];
System.arraycopy(src_array, 0 , dest_array, 0 , 19 );
System.out.println( "Source array:" + String.valueOf(src_array));
System.out.println( "Destination array after arraycopy:" + String.valueOf(dest_array));
}
}
|
输出:
在上面的程序中,我们使用“ arraycopy”方法将一个数组复制到另一个数组。您可以看到对arraycopy方法的调用。我们从开头(第0个位置)复制源数组,然后复制整个数组。
最后,我们显示源数组和目标数组的等效字符串。
使用arraycopy方法,您甚至可以复制部分数组,因为它将开始和结束元素位置作为参数。此方法对数组元素进行浅表复制。
使用Arrays.copyOf()
方法Arrays.copyOf()在内部使用System.arraycopy()方法。尽管它不如arraycopy高效,但可以像arraycopy方法一样用于复制完整或部分数组。
“ copyOf()”方法是java.util包的一部分,属于“ Arrays”类。
此方法的原型如下:
public static int [] copyOf( int [] original_array, int newLength)
|
哪里,
- original:要复制到新阵列的阵列。
- newLength:要返回的复制数组的长度。
因此,此方法通过将长度0截断或填充到新数组,从而将第一个参数中提供的数组的副本复制到指定的长度。这意味着,如果复制的数组的长度大于原始数组的长度,则其余元素将替换为0。
下面给出的程序显示了copyOf方法的示例。
importjava.util.Arrays;
public class Main
{
public static void main(String args[])
{
// define original array
int [] even_Array = new int [] { 2 , 4 , 6 , 8 };
System.out.println( "Original Array:" + Arrays.toString(even_Array));
// copying array even_Array to copy_Array
int [] copy_Array = Arrays.copyOf(even_Array, 5 );
System.out.println( "Copied Array:" + Arrays.toString(copy_Array));
// assign value to unassigned element of copied array
copy_Array[ 4 ] = 10 ;
System.out.println( "Copied and modified Array:" + Arrays.toString(copy_Array));
}
}
|
输出:
在上面的程序中,我们使用copyOf方法复制了长度为4的even_Array。提供的第二个参数是5。因此,新复制的数组中包含5个元素。前四个与原始数组相同,而第五个元素在copyOf填充时为0,因为原始数组的长度小于新数组的长度。
使用Arrays.copyOfRange()
当您要复制部分数组时,特别使用Arrays.copyOfRange()方法。与copyOf()方法一样,此方法在内部也使用System.arraycopy()方法。
Arrays.copyOfRange()方法的原型如下:
public static short [] copyOfRange( short [] original, int from, int to)
|
哪里,
- original:要从中复制范围的数组。
- from:要复制范围的初始索引(包括)。
- to:要复制的范围的最终索引(不包括)。
下面显示了copyOfRange方法的示例实现。
import java.util.Arrays;
class Main {
public static void main(String args[])
{
int intArray[] = { 10 , 20 , 30 , 40 , 50 };
// to index is within the range
int [] copyArray = Arrays.copyOfRange(intArray, 2 , 6 );
System.out.println( "Array copy with both index within the range: " +
Arrays.toString(copyArray));
//to index is out of range
int [] copy1 = Arrays.copyOfRange(intArray, 4 , intArray.length + 3 );
System.out.println( "Array copy with to index out of range: " + Arrays.toString(copy1));
}
}
|
输出:
使用Object.clone()
Java数组在内部实现了Cloneable接口,因此克隆Java数组很容易。您可以克隆一维数组和二维数组。克隆一维数组时,它会复制要复制值的数组元素。
另一方面,当您克隆二维或多维数组时,将进行元素的浅表复制,即仅复制引用。数组的克隆是通过数组提供的'Clone()'方法完成的。
克隆产生的一维数组的深层副本可以表示如下:
现在,让我们在Java程序中实现一维数组克隆。
class Main
{
public static void main(String args[])
{
int num_Array[] = { 5 , 10 , 15 , 20 , 25 , 30 };
int clone_Array[] = num_Array.clone();
System.out.println( "Original num_Array:" );
for ( int i = 0 ; i <num_Array.length; i++) {
System.out.print(num_Array[i]+ " " );
}
System.out.println();
System.out.println( "Cloned num_Array:" );
for ( int i = 0 ; i <clone_Array.length; i++) {
System.out.print(clone_Array[i]+ " " );
}
System.out.println( "\n" );
System.out.print( "num_Array == clone_Array = " );
System.out.println(num_Array == clone_Array);
}
}
|
输出:
如您在输出中所看到的,用于检查两个数组是否相等的表达式返回false。这是因为克隆一维数组会导致深度复制,其中将值复制到新数组中,而不仅仅是引用。
经常问的问题
Q#1)如何用Java复制数组?
答:复制数组有多种方法。
- 您可以使用for循环并将一个元素复制到另一个。
- 使用clone方法克隆数组。
- 使用System类的arraycopy()方法。
- 使用Arrays类的copyOf()或copyOfRange()方法。
问#2)如何将一个数组分配给另一个数组?
答:您可以使用简单的赋值运算符(=)将数组分配给另一个数组。您必须确保两个数组具有相同的数据类型并具有相同的维度。
Q#3)什么是浅拷贝和深拷贝?
答:在浅表复制中,仅复制有关对象或数组的属性。因此,对复制数组的任何更改都将反映在原始数组中。Java克隆是浅表副本的示例。
深层副本是其中我们需要对象的完整副本的副本,以便在我们克隆或复制该对象时,它是独立副本。当涉及原始或内置类型时,浅表副本和深表副本之间没有区别。
Q#4)阵列克隆做什么?
答:数组的克隆方法用于将一个对象的属性复制到另一个对象。为此,它使用浅表副本。
问#5)可以将数组存储在数组中吗?
答:数组可以包含带有相同类型(原始或对象)元素的数组。这意味着您不能在字符串数组中存储整数数组。
结论
在本教程中,我们探索了Java中的复制数组和克隆数组。我们已经看到了复制和克隆数组的各种方法/方法。
请注意,大多数这些方法都实现了浅表复制。对于原始数据类型,浅拷贝和深拷贝没有区别。但是,当数组包含对象或引用时,程序员需要根据要求实现深层副本。