Я играл с лямбдами Java 8, чтобы легко фильтровать коллекции. Но я не нашел краткий способ получить результат в виде нового списка в том же утверждении. Вот мой самый лаконичный подход:
List<Long> sourceLongList = Arrays.asList(1L, 10L, 50L, 80L, 100L, 120L, 133L, 333L);
List<Long> targetLongList = new ArrayList<>();
sourceLongList.stream().filter(l -> l > 100).forEach(targetLongList::add);
Примеры в сети не ответили на мой вопрос, потому что они останавливаются без создания нового списка результатов. Должен быть более лаконичный способ. Я бы ожидал, что Stream
класс имеет методы , как toList()
, toSet()
...
Есть ли способ, которым переменные targetLongList
могут быть непосредственно назначены третьей строкой?
collections
lambda
java-8
java-stream
Даниэль К.
источник
источник
sourceLongList
потом естьCollection.removeIf(…)
для удобства.List<Long> targetLongList = sourceLongList.stream().collect(Collectors.toList());
Ответы:
То, что вы делаете, может быть самым простым способом, при условии, что ваш поток остается последовательным - в противном случае вам придется предварительно вызвать вызов sequential ()
forEach
.[позднее редактирование: причина, по которой вызов sequential () необходим, заключается в том, что код в том виде, в котором он стоит (
forEach(targetLongList::add)
), был бы нечетким, если бы поток был параллельным. Даже в этом случае не будет достигнут ожидаемый эффект, посколькуforEach
он явно недетерминирован - даже в последовательном потоке порядок обработки элементов не гарантируется. Вы должны использоватьforEachOrdered
для обеспечения правильного заказа. Целью разработчиков Stream API является то, что вы будете использовать коллектор в этой ситуации, как показано ниже.]Альтернатива
источник
toList
. Это делается путем размещения следующих среди импорта файла:static import java.util.stream.Collectors.toList;
. Тогда вызов вызова читает просто.collect(toList())
.Collectors
класс в « Предпочтения» -> « Java» -> « Редактор» -> « Помощник по содержимому» -> « Избранное» . После этого вам нужно всего лишьtoLi
нажать Ctrl + Space, чтобы заполнить IDEtoList
и добавить статический импорт.IntStream
некоторых и других почти, но не совсемStream
, нетcollect(Collector)
метода, и вам придется вызыватьIntStream.boxed()
их, чтобыStream
сначала преобразовать их в обычный . Опять же, может быть, вы просто хотитеtoArray()
.sequential()
раньшеforEach
или использовать forEachOrderedОбновлено:
Другой подход заключается в использовании
Collectors.toList
:Предыдущее решение:
Другой подход заключается в использовании
Collectors.toCollection
:источник
Collectors::toList
javadoc: «Нет никаких гарантий относительно типа, изменчивости, сериализуемости или безопасности потока возвращаемого списка; если требуется больше контроля над возвращенным списком, используйтеtoCollection(Supplier)
».Мне нравится использовать метод util, который возвращает коллектор,
ArrayList
когда это то, что я хочу.Я думаю, что использование решения
Collectors.toCollection(ArrayList::new)
немного слишком шумно для такой обычной операции.Пример:
Этим ответом я также хочу продемонстрировать, насколько просто создавать и использовать пользовательские коллекторы, что в целом очень полезно.
источник
toList
если вы, например, хотите изменить список позже в программе.toList
Документация говорит следующее: «Там нет никаких гарантий по типу, изменчивости, сериализуемости или потокобезопасности Списка возвращаемых, если больший контроль над возвращаемым списком требуется, использованиеtoCollection
.» , Мой ответ демонстрирует способ сделать это более удобным в обычном случае.Если у вас есть массив примитивов, вы можете использовать коллекции примитивов, доступные в Eclipse Collections .
Если вы не можете изменить sourceLongList с
List
:Если вы хотите использовать
LongStream
:Примечание: я участвую в коллекциях Eclipse.
источник
Немного более эффективный способ (избегайте создания исходного списка и автоматической распаковки с помощью фильтра):
источник
Это вызов, который вы можете использовать для преобразования любого потока в список.
более конкретно:
от:
https://www.geeksforgeeks.org/collectors-tolist-method-in-java-with-examples/
источник
Если вы не возражаете против использования сторонних библиотек, в библиотеке AOL cyclops-реагировать (раскрытие которой я участвую) есть расширения для всех типов JDK Collection , включая List . Интерфейс ListX расширяет java.util.List и добавляет большое количество полезных операторов, включая фильтр.
Вы можете просто написать
ListX также может быть создан из существующего списка (через ListX.fromIterable)
источник
Существует еще один вариант метода сбора данных, предоставляемый классом LongStream, а также классами IntStream и DoubleStream.
Выполняет изменяемую операцию сокращения над элементами этого потока. Изменяемое сокращение - это такое, в котором уменьшенное значение представляет собой изменяемый контейнер результатов, такой как ArrayList, и элементы включаются путем обновления состояния результата, а не путем замены результата. Это дает результат, эквивалентный:
Как и Reduce (long, LongBinaryOperator), операции сбора могут быть распараллелены без дополнительной синхронизации. Это терминальная операция.
И ответ на ваш вопрос с этим методом сбора, как показано ниже:
Ниже приведен вариант справочника по методам, который довольно умен, но несколько сложен для понимания:
Ниже будет вариант HashSet:
Аналогично вариант LinkedList выглядит так:
источник
Если кто-то (например, я) ищет способы взаимодействия с объектами вместо примитивных типов, тогда используйте
mapToObj()
печатает:
источник
источник
Вот код от AbacusUtil
Раскрытие информации: я разработчик AbacusUtil.
источник
com.landawn.abacus.util.stream.LongStream
илиLongStreamEx
в AbacusUtilВы можете переписать код, как показано ниже:
источник
Чтобы собрать в изменяемый список:
Собрать в неизменном списке:
Объяснение
collect
из JavaDoc :источник
Если вы не используете
parallel()
это будет работатьисточник
collect
а затем не сохранять возвращаемое значение. В этом случае вы можете использоватьforEach
вместо этого. Но это все еще плохое решение.