it-roy-ru.com

Как скопировать Java.util.List в другой Java.util.List

У меня есть List<SomeBean>, который заполняется из веб-службы. Я хочу скопировать/клонировать содержимое этого списка в пустой список того же типа. Поиск в Google для копирования списка предложил мне использовать метод Collections.copy(). Во всех примерах, которые я видел, список адресатов должен был содержать точное количество элементов для копирования. 

Поскольку список, который я использую, заполняется через веб-сервис и содержит сотни объектов, я не могу использовать вышеуказанную технику. Или я использую это неправильно ?? !! В любом случае, чтобы это работало, я пытался сделать что-то вроде этого, но я все еще получил IndexOutOfBoundsException.

List<SomeBean> wsList = app.allInOne(template);

List<SomeBean> wsListCopy=new ArrayList<SomeBean>(wsList.size());   
Collections.copy(wsListCopy,wsList);
System.out.println(wsListCopy.size());

Я пытался использовать функцию wsListCopy=wsList.subList(0, wsList.size()), но позже я получил ConcurrentAccessException в коде. Хит и пробный. :)

В любом случае, мой вопрос прост, как я могу скопировать все содержимое моего списка в другой список? Не через итерацию, конечно. 

108
Mono Jamoon

Просто используйте это:

List<SomeBean> newList = new ArrayList<SomeBean>(otherList);

Примечание: по-прежнему не является поточно-ориентированным, если вы измените otherList из другого потока, то вы можете сделать это otherList (и даже newList), например, CopyOnWriteArrayList - или использовать примитив блокировки, такой как ReentrantReadWriteLock для сериализации доступа на чтение/запись к любым спискам, к которым одновременно осуществляется доступ.

206
fge

Это действительно хороший Java 8 способ сделать это:

List<String> list2 = list1.stream().collect(Collectors.toList());

Конечно, преимущество в том, что вы можете фильтровать и пропустить только копию части списка.

например.

//don't copy the first element 
List<String> list2 = list1.stream().skip(1).collect(Collectors.toList());
26
Dan
originalArrayList.addAll(copyArrayofList);

Пожалуйста, имейте в виду, что при использовании метода addAll () для копирования содержимое обоих списков массивов (originalArrayList и copyArrayofList), ссылающихся на одни и те же объекты, будет добавлено в список, поэтому, если вы измените какой-либо из них, copyArrayofList также будет отражать те же изменения.

Если вам не нужен побочный эффект, вам нужно скопировать каждый элемент из originalArrayList в copyArrayofList, например, используя цикл for или while.

8
Divyesh Kanzariya

Я пытался сделать что-то подобное, но я все еще получил исключение IndexOutOfBoundsException.

Я получил ConcurrentAccessException 

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

  • использовать коллекцию, которая предназначена для одновременного доступа. 

  • заблокируйте коллекцию соответствующим образом, чтобы вы могли перебирать ее (или позволить вызывать метод, который сделает это за вас)

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

7
Peter Lawrey

В Java 10:

List<T> newList = List.copyOf(oldList);

List.copyOf() возвращает неизменяемый List, содержащий элементы данного Collection.

Указанная Collection не должна быть null и не должна содержать никаких элементов null.

2
Oleksandr

Есть еще один метод с Java 8 в нулевом безопасном режиме.

List<SomeBean> wsListCopy = Optional.ofNullable(wsList)
                                    .map(List::stream)
                                    .orElseGet(Stream::empty)
                                    .collect(Collectors.toList());

Если вы хотите пропустить один элемент.

List<SomeBean> wsListCopy = Optional.ofNullable(wsList)
                                    .map(List::stream)
                                    .orElseGet(Stream::empty)
                                    .skip(1)
                                    .collect(Collectors.toList());
2
Nicolas Henneaux

У меня была та же проблема ConcurrentAccessException и mysolution должен был:

List<SomeBean> tempList = new ArrayList<>();

for (CartItem item : prodList) {
  tempList.add(item);
}
prodList.clear();
prodList = new ArrayList<>(tempList);

Таким образом, он работает только одну операцию за один раз и избегает исключения ...

1
T04435

Я попытался что-то подобное и смог воспроизвести проблему (IndexOutOfBoundsException). Ниже приведены мои выводы:

1) Реализация Collections.copy (destList, sourceList) сначала проверяет размер списка адресатов, вызывая метод size (). Поскольку вызов метода size () всегда возвращает количество элементов в списке (в данном случае 0), конструктор ArrayList (Capacity) обеспечивает только начальную емкость массива поддержки, и это не имеет никакого отношения к размер списка. Следовательно, мы всегда получаем IndexOutOfBoundsException.

2) Относительно простым способом является использование конструктора, который принимает коллекцию в качестве аргумента:

List<SomeBean> wsListCopy=new ArrayList<SomeBean>(wsList);  
1
Abhay Yadav

Вы можете использовать addAll ().

например: wsListCopy.addAll(wsList);

0
samaludheen cignes

re: indexOutOfBoundsException, ваши аргументы подсписка являются проблемой; Вы должны закончить подсписок в размере 1. Начиная с нуля, последним элементом списка всегда является размер-1, в позиции размера отсутствует элемент, следовательно, ошибка.

0
Jon Nelson

Я не вижу правильного ответа. Если вы хотите глубокое копирование, вам нужно итерировать и копировать объект вручную (вы можете использовать конструктор копирования).

0
The incredible Jan