Условия: не изменять оригинальные списки; Только JDK, без внешних библиотек. Бонусные баллы за однострочную версию или версию JDK 1.3.
Есть ли более простой способ, чем:
List<String> newList = new ArrayList<String>();
newList.addAll(listOne);
newList.addAll(listTwo);
Ответы:
В Java 8:
источник
List<String> newList = Stream.concat(listOne.stream(), listTwo.stream()).distinct().collect(Collectors.toList());
Stream.of(listOne, listTwo).flatMap(Collection::stream).collect(Collectors.toList())
Вне головы я могу сократить его на одну строку:
источник
addAll()
того, и другого. Я перепробовал все те, которые предлагают не копировать списки, и они приводят к большим накладным расходам, которые нам не понадобились на этот раз.addAll(Collection)
возвращаетboolean
.Вы можете использовать библиотеку Apache commons-collection :
источник
Одно из ваших требований - сохранить оригинальные списки. Если вы создаете новый список и используете его
addAll()
, вы фактически удваиваете количество ссылок на объекты в ваших списках. Это может привести к проблемам с памятью, если ваши списки очень большие.Если вам не нужно изменять объединенный результат, вы можете избежать этого, используя собственную реализацию списка. Очевидно, что пользовательский класс реализации состоит из нескольких строк, но его использование короткое и приятное.
CompositeUnmodifiableList.java:
Применение:
источник
Collections.unmodifiableList()
метод, который оборачивает список, чтобы сделать его неизменяемым.CompositeUnmodifiableList
делает то же самое, за исключением того, что оборачивает два списка и обеспечивает объединенное представление. Все пункты, оCompositeUnmodifiableList
которых вы говорите , также верныCollections.unmodifiableList()
.List<? extends E>
Наверное, не проще, но интригующе и некрасиво
Не используйте его в производственном коде ...;)
источник
Еще одна однострочная версия Java 8:
В качестве бонуса, поскольку
Stream.of()
он варьируется, вы можете объединить столько списков, сколько захотите.источник
x -> x.stream()
можно заменить наCollection::stream
.List::stream
.Не проще, но без изменения размера накладных расходов:
источник
Нашел этот вопрос, стремясь объединить произвольное количество списков, не обращая внимания на внешние библиотеки. Так что, возможно, это поможет кому-то еще:
Полезно, если вы хотите применить одну и ту же логику к нескольким различным коллекциям в одной for ().
источник
com.google.common.collect.Iterators#concat(java.util.Iterator<? extends java.util.Iterator<? extends T>>)
вместоIterables#concat()
; потому что позже все еще копируют элементы во временную ссылку!Предлагаемое решение предназначено для трех списков, хотя оно может применяться и для двух списков. В Java 8 мы можем использовать Stream.of или Stream.concat как:
Stream.concat
принимает два потока в качестве входных данных и создает ленивый каскадный поток, элементами которого являются все элементы первого потока, за которыми следуют все элементы второго потока. Поскольку у нас есть три списка, мы использовали этот метод (Stream.concat
) два раза.Мы также можем написать служебный класс с методом, который принимает любое количество списков (используя varargs ) и возвращает объединенный список в виде:
Тогда мы можем использовать этот метод как:
источник
Вот решение Java 8 с использованием двух строк:
Помните, что этот метод не следует использовать, если
newList
неизвестно и может уже передаваться другим потокамnewList
является параллельным потоком, и доступ к немуnewList
не синхронизирован или не является потокобезопаснымиз-за побочных эффектов.
Оба вышеперечисленных условия не применяются для вышеуказанного случая объединения двух списков, так что это безопасно.
На основании этого ответа на другой вопрос.
источник
newList
не наблюдается ни один другой поток. Но вы правы, что этого, вероятно, не следует делать, если неизвестно, откудаnewList
пришло значение (например, если оноnewList
было передано в качестве параметра..forEach(newList::addAll);
вместо.collect(Collectors.toList());
?List<List<Object>>
. Вы можете иметь в виду что-то вроде этого: stackoverflow.com/questions/189559/…flatMap
.Это просто и всего одна строка, но добавит содержимое listTwo в listOne. Вы действительно должны поместить содержимое в третий список?
источник
Немного проще:
источник
List
Структура не накладывает никаких ограничений уникальности. Вы можете удалить обманщиков, делая то же самое с сетами.Set<String> newSet = new HashSet<>(setOne); newSet.addAll(setTwo);
Немного короче было бы:
источник
Вы можете создать свой универсальный метод утилит Java 8 для объединения любого количества списков .
источник
Вы можете сделать oneliner, если целевой список предварительно объявлен.
источник
В Java 8 (другой способ):
источник
еще одно линейное решение с использованием
Java8
потока, так какflatMap
решение уже опубликовано, вот решение безflatMap
или
код
вывод
источник
flatMap
, потому что списки повторяются только один раз, когда они собираютсяСамые умные на мой взгляд:
источник
@SafeVarargs
!Вы можете сделать это с помощью статического импорта и вспомогательного класса
нб родовые этого класса, вероятно , может быть улучшены
Тогда вы можете делать такие вещи, как
источник
Версия Java 8 с поддержкой соединения по ключу объекта:
источник
источник
Используйте вспомогательный класс.
Я предлагаю:
источник
источник
Мы можем объединить 2 списка, используя java8 с 2 подходами.
1) Используя concat:
2) Использование flatMap:
источник
Почти из ответов предлагается использовать ArrayList.
Предпочитаю использовать LinkedList для эффективных операций добавления.
ArrayList add является O (1) амортизированным, но O (n) худшим случаем, так как размер массива должен быть изменен и скопирован. При этом LinkedList add всегда постоянен O (1).
больше информации https://stackoverflow.com/a/322742/311420
источник
Я не утверждаю, что это просто, но вы упомянули бонус для однострочников ;-)
источник
Недалеко от одной строки, но я думаю, что это самое простое:
источник
Вот подход с использованием потоков и Java 8, если ваши списки имеют разные типы, и вы хотите объединить их в список другого типа.
источник
Если вы хотите сделать это статически, вы можете сделать следующее.
В примерах используются 2 EnumSets в естественном порядке (== Enum-порядок)
A, B
и затем объединяются вALL
список.источник
источник