2009-10-14 33 views

Trả lời

48

Có, bạn nên lặp qua mảng boolean 2D để sao chép sâu nó. Ngoài ra nhìn vào java.util.Arrays#copyOf phương pháp nếu bạn đang ở trên Java 6.

tôi sẽ đề nghị các mã tiếp theo cho Java 6:

public static boolean[][] deepCopy(boolean[][] original) { 
    if (original == null) { 
     return null; 
    } 

    final boolean[][] result = new boolean[original.length][]; 
    for (int i = 0; i < original.length; i++) { 
     result[i] = Arrays.copyOf(original[i], original[i].length); 
     // For Java versions prior to Java 6 use the next: 
     // System.arraycopy(original[i], 0, result[i], 0, original[i].length); 
    } 
    return result; 
} 
+0

Lưu ý rằng điều này dường như không làm việc cho 'Objects'. Xem http://stackoverflow.com/questions/15135104/system-arraycopy-copies-object-or-reference-to-object – Timo

5

Vâng, đó là cách duy nhất để làm điều đó. Không phải java.util.Arrays không phải commons-lang cung cấp bản sao sâu cho mảng.

6

Tôi là người hâm mộ tiện ích Arrays. Nó có một phương pháp copyOf rằng sẽ làm một bản sao sâu sắc về một mảng 1-D cho bạn, vì vậy bạn muốn một cái gì đó như thế này:

//say you have boolean[][] foo; 
boolean[][] nv = new boolean[foo.length][foo[0].length]; 
for (int i = 0; i < nv.length; i++) 
    nv[i] = Arrays.copyOf(foo[i], foo[i].length); 
+6

Lưu ý rằng điều này chỉ tạo ra một "bản sao sâu" cho các loại nguyên thủy! Bản thân Arrays.copyOf() chỉ tạo ra các bản sao nông. – codepleb

7

tôi đã quản lý để đưa ra một bản sao sâu mảng đệ quy. Dường như nó hoạt động khá tốt ngay cả đối với mảng đa chiều với độ dài thứ nguyên khác nhau, ví dụ:

private static final int[][][] INT_3D_ARRAY = { 
     { 
       {1} 
     }, 
     { 
       {2, 3}, 
       {4, 5} 
     }, 
     { 
       {6, 7, 8}, 
       {9, 10, 11}, 
       {12, 13, 14} 
     } 
}; 

Đây là phương pháp tiện ích.

@SuppressWarnings("unchecked") 
public static <T> T[] deepCopyOf(T[] array) { 

    if (0 >= array.length) return array; 

    return (T[]) deepCopyOf(
      array, 
      Array.newInstance(array[0].getClass(), array.length), 
      0); 
} 

private static Object deepCopyOf(Object array, Object copiedArray, int index) { 

    if (index >= Array.getLength(array)) return copiedArray; 

    Object element = Array.get(array, index); 

    if (element.getClass().isArray()) { 

     Array.set(copiedArray, index, deepCopyOf(
       element, 
       Array.newInstance(
         element.getClass().getComponentType(), 
         Array.getLength(element)), 
       0)); 

    } else { 

     Array.set(copiedArray, index, element); 
    } 

    return deepCopyOf(array, copiedArray, ++index); 
} 

EDIT: Cập nhật mã để làm việc với mảng nguyên thủy.

+0

Điều này có vẻ tốt. 'Array' là gì? – elgehelge

+2

Chỉnh sửa: Tự tìm ra: 'import java.lang.reflect.Array;' – elgehelge

2

Trong Java 8 này có thể được thực hiện như một lớp lót bằng lambdas:

<T> T[][] deepCopy(T[][] matrix) { 
    return java.util.Arrays.stream(matrix).map(el -> el.clone()).toArray($ -> matrix.clone()); 
} 
+1

Sử dụng 'clone()' hiếm khi là một ý tưởng hay. – Ypnypn

+2

@Ypnypn Tôi hoàn toàn đồng ý, ngoại trừ các mảng. Sử dụng 'clone()' thường là cách nhanh nhất và đơn giản nhất để sao chép một mảng. – SlavaSt

+0

'clone()' cho mảng là hoàn toàn tốt. –

Các vấn đề liên quan