-
Enhancement
-
Resolution: Unresolved
-
P4
-
None
-
8, 9
-
generic
-
generic
A DESCRIPTION OF THE REQUEST :
In the class Arrays of the package java.util there isn't a method that allows deep copy of multiarrays.
JUSTIFICATION :
This enhancement is necessary for coping a multiarray that should be assigned to a field or returned by a getter method, to ensure that the data structure will not be modified externally of the class.
---------- BEGIN SOURCE ----------
import java.util.Arrays;
public class Test {
public static void main(String[] args) {
int[][] array1=new int[2][2];
//the Arrays.copyOf and array1.clone methods perform a shallow copy of array1
int[][] array2=Arrays.copyOf(array1, array1.length);
int[][] array3=array1.clone();
//array1, array2, array3 are different arrays because their internal addresses aren't equal
System.out.println("Internal address of array1: "+System.identityHashCode(array1));
System.out.println("Internal address of array2: "+System.identityHashCode(array2));
System.out.println("Internal address of array3: "+System.identityHashCode(array3));
System.out.println();
//elements of array1, array2, array3 are the same because they have equal internal addresses
System.out.println("Element's internal addresses of array1:");
for(int i=0;i<array1.length;i++)
System.out.println(System.identityHashCode(array1[i]));
System.out.println("Element's internal addresses of array2:");
for(int i=0;i<array2.length;i++)
System.out.println(System.identityHashCode(array2[i]));
System.out.println("Element's internal addresses of array3:");
for(int i=0;i<array3.length;i++)
System.out.println(System.identityHashCode(array3[i]));
System.out.println();
//the modifications performed on an array are reflected on the others
array1[0][0]=1;
System.out.println("array1[0][0]=1;");
System.out.println("array1:\n"+Arrays.deepToString(array1));
System.out.println("array2:\n"+Arrays.deepToString(array2));
System.out.println("array3:\n"+Arrays.deepToString(array3));
System.out.println();
array2[0][1]=2;
System.out.println("array2[0][1]=2;");
System.out.println("array1:\n"+Arrays.deepToString(array1));
System.out.println("array2:\n"+Arrays.deepToString(array2));
System.out.println("array3:\n"+Arrays.deepToString(array3));
System.out.println();
array3[1][0]=3;
System.out.println("array3[1][0]=3;");
System.out.println("array1:\n"+Arrays.deepToString(array1));
System.out.println("array2:\n"+Arrays.deepToString(array2));
System.out.println("array3:\n"+Arrays.deepToString(array3));
System.out.println();
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
import java.lang.reflect.Array;
import java.util.HashMap;
public class Utils {
public static <T> T[] deepCopyOf(T[] array){
return deepCopyOf(array, new HashMap<>());
}
@SuppressWarnings("unchecked")
private static <T> T deepCopyOf(T array, HashMap<Object, Object> dejavu){
T copy=(T) dejavu.get(array);
if(copy==null){
Class<?> componentType=array.getClass().getComponentType();
int length=Array.getLength(array);
copy=(T) Array.newInstance(componentType, length);
boolean multiarray=componentType.isArray();
dejavu.put(array, copy);
if(multiarray || componentType==Object.class){
Object[] src=(Object[]) array, dest=(Object[]) copy;
if(multiarray){
for(int i=0;i<length;i++){
Object o=src[i];
dest[i]=(o!=null) ? deepCopyOf(o, dejavu) : null;
}
}else{
for(int i=0;i<length;i++){
Object o=src[i];
dest[i]=(o!=null && o.getClass().isArray()) ? deepCopyOf(o, dejavu) : o;
}
}
}else
System.arraycopy(array, 0, copy, 0, length);
}
return copy;
}
}
In the class Arrays of the package java.util there isn't a method that allows deep copy of multiarrays.
JUSTIFICATION :
This enhancement is necessary for coping a multiarray that should be assigned to a field or returned by a getter method, to ensure that the data structure will not be modified externally of the class.
---------- BEGIN SOURCE ----------
import java.util.Arrays;
public class Test {
public static void main(String[] args) {
int[][] array1=new int[2][2];
//the Arrays.copyOf and array1.clone methods perform a shallow copy of array1
int[][] array2=Arrays.copyOf(array1, array1.length);
int[][] array3=array1.clone();
//array1, array2, array3 are different arrays because their internal addresses aren't equal
System.out.println("Internal address of array1: "+System.identityHashCode(array1));
System.out.println("Internal address of array2: "+System.identityHashCode(array2));
System.out.println("Internal address of array3: "+System.identityHashCode(array3));
System.out.println();
//elements of array1, array2, array3 are the same because they have equal internal addresses
System.out.println("Element's internal addresses of array1:");
for(int i=0;i<array1.length;i++)
System.out.println(System.identityHashCode(array1[i]));
System.out.println("Element's internal addresses of array2:");
for(int i=0;i<array2.length;i++)
System.out.println(System.identityHashCode(array2[i]));
System.out.println("Element's internal addresses of array3:");
for(int i=0;i<array3.length;i++)
System.out.println(System.identityHashCode(array3[i]));
System.out.println();
//the modifications performed on an array are reflected on the others
array1[0][0]=1;
System.out.println("array1[0][0]=1;");
System.out.println("array1:\n"+Arrays.deepToString(array1));
System.out.println("array2:\n"+Arrays.deepToString(array2));
System.out.println("array3:\n"+Arrays.deepToString(array3));
System.out.println();
array2[0][1]=2;
System.out.println("array2[0][1]=2;");
System.out.println("array1:\n"+Arrays.deepToString(array1));
System.out.println("array2:\n"+Arrays.deepToString(array2));
System.out.println("array3:\n"+Arrays.deepToString(array3));
System.out.println();
array3[1][0]=3;
System.out.println("array3[1][0]=3;");
System.out.println("array1:\n"+Arrays.deepToString(array1));
System.out.println("array2:\n"+Arrays.deepToString(array2));
System.out.println("array3:\n"+Arrays.deepToString(array3));
System.out.println();
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
import java.lang.reflect.Array;
import java.util.HashMap;
public class Utils {
public static <T> T[] deepCopyOf(T[] array){
return deepCopyOf(array, new HashMap<>());
}
@SuppressWarnings("unchecked")
private static <T> T deepCopyOf(T array, HashMap<Object, Object> dejavu){
T copy=(T) dejavu.get(array);
if(copy==null){
Class<?> componentType=array.getClass().getComponentType();
int length=Array.getLength(array);
copy=(T) Array.newInstance(componentType, length);
boolean multiarray=componentType.isArray();
dejavu.put(array, copy);
if(multiarray || componentType==Object.class){
Object[] src=(Object[]) array, dest=(Object[]) copy;
if(multiarray){
for(int i=0;i<length;i++){
Object o=src[i];
dest[i]=(o!=null) ? deepCopyOf(o, dejavu) : null;
}
}else{
for(int i=0;i<length;i++){
Object o=src[i];
dest[i]=(o!=null && o.getClass().isArray()) ? deepCopyOf(o, dejavu) : o;
}
}
}else
System.arraycopy(array, 0, copy, 0, length);
}
return copy;
}
}
- relates to
-
JDK-4106818 Provide a general way to make deep copies of objects
- Open
-
JDK-5101827 Adding a Copyable interface to java.lang
- Open