Как сделать разделенную копию ArrayList? [дубликат]

Другой перечисленный Стандартом C++:

#include <stdio.h>

int x[1];
int main(void) {
    struct x { int a[2]; };
    /* size of the array in C */
    /* size of the struct in C++ */
    printf("%d\n", (int)sizeof(x)); 
}
25
задан Community 23 May 2017 в 12:26
поделиться

4 ответа

Да, это правильно - вам необходимо реализовать clone () (или другой подходящий механизм для копирования вашего объекта, поскольку считается clone () » сломан "многими программистами). Ваш метод clone () должен выполнять глубокую копию всех изменяемых полей в вашем объекте. Таким образом, изменения клонированного объекта не повлияют на оригинал.

В вашем примере кода вы создаете второй ArrayList и заполняете его ссылками на те же объекты , поэтому изменения в объекте видны из обоих List s. При использовании подхода клонирования ваш код будет выглядеть так:

List<Foo> originalList = ...;

// Create new List with same capacity as original (for efficiency).
List<Foo> copy = new ArrayList<Foo>(originalList.size());

for (Foo foo: originalList) {
  copy.add((Foo)foo.clone());
}

РЕДАКТИРОВАТЬ : Чтобы уточнить, приведенный выше код выполняет глубокую копию исходного Списка , при этом новый Список содержит ссылки на копии исходных объектов. Это контрастирует с вызовом ArrayList.clone () , который выполняет мелкую копию списка List . В этом контексте неглубокая копия создает новый экземпляр List , но содержащий ссылки на исходные объекты.

39
ответ дан 28 November 2019 в 18:31
поделиться

Я подумал, что могу изменить элементы внутри copiedInvoice, и это не повлияет на эти элементы внутри originalInoice.

Это происходит потому, что копируется ссылочная переменная, а не сам объект.

Таким образом, вы получаете две «ссылки», указывающие на один и тот же объект.

Если вам нужно скопировать весь объект, вам может потребоваться его клонирование.

Но у вас могут возникнуть проблемы, если вы не клонируете внутренние атрибуты объекта, если они являются другими объектами.

Например, следующее определение класса не вызовет у вас никаких проблем.

  public class Something {
       private int x;
       private int y;
       private String stringObject;
   }

Если вы создадите копию этого класса, вы скопируете текущие значения его атрибутов и все.

Но если у вашего класса есть другой объект внутри, вы можете подумать о его клонировании.

 class OtherSomething {
        Something something;
       private int x;
 }

Если вы сделаете следующее:

 Something shared = new Something();

 OtherSomething one = new OtherSomething();

 OtherSomething two = new OtherSomething();

 one.something = shared;
 two.something = shared;

В этом случае и один, и два имеют одну и ту же ссылочную переменную на одно и то же совместно используемое «что-то», и изменение значения в одном из них повлияет на другое.

Вот почему гораздо проще / лучше / проще использовать неизменяемые объекты.

Если вам нужно изменить значение неизменяемого объекта, вы просто создаете новый с правильным значением.

2
ответ дан 28 November 2019 в 18:31
поделиться

Если вы сохраняете изменяемые объекты в ArrayList, вам нужно будет скопировать каждый объект при копировании ArrayList. В противном случае новый список ArrayList по-прежнему будет содержать исходные ссылки.

Однако, если вы храните неизменяемые объекты, можно использовать:

ArrayList copiedInvoice = new ArrayList (originalInvoice);

18
ответ дан 28 November 2019 в 18:31
поделиться

Взгляните на ByteArrayOutputStream и ByteArrayInputStream. Если все ваши классы реализуют Serializable, вы можете сделать копию, используя вышеупомянутые классы.

-1
ответ дан 28 November 2019 в 18:31
поделиться
Другие вопросы по тегам:

Похожие вопросы: