Глубокое клонирование многомерных массивов в Java ...?

У меня есть два многомерных массива (ну, на самом деле они всего лишь 2D), которые имеют предполагаемый размер. Как мне их глубоко клонировать? Вот что я получил на данный момент:

public foo(Character[][] original){
    clone = new Character[original.length][];
    for(int i = 0; i < original.length; i++)
          clone[i] = (Character[]) original[i].clone();
}

Тест на равенство original.equals(clone); выдает ложный результат. Почему? : |

Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
7
0
12 374
6

Ответы 6

Возможно, вы захотите проверить методы java.util.Arrays.deepEquals и java.util.Arrays.equals.

Я боюсь, что метод equals для объектов массива выполняет неглубокое сравнение и неправильно (по крайней мере, в этом случае) сравнивает внутренние массивы Character.

Метод equals () для массивов - это метод, объявленный в классе Object. Это означает, что он вернет истину только в том случае, если объекты такие же. То же самое означает не то же самое в СОДЕРЖАНИЕ, но то же самое в ПАМЯТИ. Таким образом, equals () в ваших массивах никогда не вернет true, поскольку вы дублируете структуру в памяти.

A test for equality original.equals(clone); spits out a false. Why? :|

это потому, что вы создаете новый массив с new Character[original.length][];.

Arrays.deepEquals(original,clone) должен вернуть истину.

Я нашел этот ответ для клонирования многомерных массивов на jGuru:

ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(this);
ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
ObjectInputStream ois = new ObjectInputStream(bais);
Object deepCopy = ois.readObject();

Этот метод работает для многомерных массивов. Просто используйте array вместо this

Venkata Raju 07.08.2014 19:56

/**Creates an independent copy(clone) of the boolean array.
 * @param array The array to be cloned.
 * @return An independent 'deep' structure clone of the array.
 */
public static boolean[][] clone2DArray(boolean[][] array) {
    int rows=array.length ;
    //int rowIs=array[0].length ;

    //clone the 'shallow' structure of array
    boolean[][] newArray =(boolean[][]) array.clone();
    //clone the 'deep' structure of array
    for(int row=0;row<rows;row++){
        newArray[row]=(boolean[]) array[row].clone();
    }

    return newArray;
}

То же, что и решение @Barak (Serialize и Deserialize) с примерами (поскольку некоторые люди не могли понять и проголосовали против)

public static <T extends Serializable> T deepCopy(T obj)
{
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    try
    {
        ObjectOutputStream oos = new ObjectOutputStream(baos);

        // Beware, this can throw java.io.NotSerializableException 
        // if any object inside obj is not Serializable
        oos.writeObject(obj);  
        ObjectInputStream ois = new ObjectInputStream(
                                    new ByteArrayInputStream(baos.toByteArray()));
        return (T) ois.readObject();
    }
    catch (  ClassNotFoundException /* Not sure */
           | IOException /* Never happens as we are not writing to disc */ e)
    {
        throw new RuntimeException(e); // Your own custom exception
    }
}

Использование:

    int[][] intArr = { { 1 } };
    System.out.println(Arrays.deepToString(intArr)); // prints: [[1]]
    int[][] intDc = deepCopy(intArr);
    intDc[0][0] = 2;
    System.out.println(Arrays.deepToString(intArr)); // prints: [[1]]
    System.out.println(Arrays.deepToString(intDc)); // prints: [[2]]
    int[][] intClone = intArr.clone();
    intClone[0][0] = 4;

    // original array modified because builtin cloning is shallow 
    System.out.println(Arrays.deepToString(intArr)); // prints: [[4]]
    System.out.println(Arrays.deepToString(intClone)); // prints: [[4]]

    short[][][] shortArr = { { { 2 } } };
    System.out.println(Arrays.deepToString(shortArr)); // prints: [[[2]]]

    // deepCopy() works for any type of array of any dimension
    short[][][] shortDc = deepCopy(shortArr);
    shortDc[0][0][0] = 4;
    System.out.println(Arrays.deepToString(shortArr)); // prints: [[[2]]]
    System.out.println(Arrays.deepToString(shortDc)); // prints: [[[4]]]

Другие вопросы по теме