Я только начал играть с лямбдами Java 8, и я пытаюсь реализовать некоторые вещи, к которым я привык в функциональных языках.
Например, большинство функциональных языков имеют какую-то функцию поиска, которая работает с последовательностями, или списки, которые возвращают первый элемент, для которого существует предикат true
. Единственный способ добиться этого в Java 8 - это:
lst.stream()
.filter(x -> x > 5)
.findFirst()
Однако это кажется мне неэффективным, так как фильтр будет сканировать весь список, по крайней мере, насколько я понимаю (что может быть неправильно). Есть ли способ лучше?
java
java-8
java-stream
Сики
источник
источник
Ответы:
Нет, фильтр не сканирует весь поток. Это промежуточная операция, которая возвращает ленивый поток (фактически все промежуточные операции возвращают ленивый поток). Чтобы убедить вас, вы можете просто сделать следующий тест:
Какие выводы:
Вы видите, что фактически обрабатываются только два первых элемента потока.
Таким образом, вы можете пойти с вашим подходом, который прекрасно подходит.
источник
get();
здесь, потому что я знаю, какие значения я передаю в потоковый конвейер и, следовательно, что будет результат. На практике не следует использоватьget();
, ноorElse()
/orElseGet()
/orElseThrow()
(для более значимой ошибки вместо NSEE), поскольку вы можете не знать, приведут ли операции, примененные к потоковому конвейеру, к элементу..findFirst().orElse(null);
напримерorElse
?Optional
тип, что и.findFirst
возвращает. Одно из применений Optional - помочь разработчикам избежать необходимости иметь дело сnull
seg вместо проверкиmyObject != null
, вы можете проверитьmyOptional.isPresent()
или использовать другие части интерфейса Optional. Это прояснило?Нет, не будет - он «сломается», как только будет найден первый элемент, удовлетворяющий предикату. Вы можете прочитать больше о лени в потоковом пакете javadoc , в частности (выделено мое):
источник
Мне пришлось отфильтровать только один объект из списка объектов. Так что я использовал это, надеюсь, это поможет.
источник
.orElse(null) != null
. Вместо этого, использовать Факультативный API,.isPresent
то есть.findFirst().isPresent()
..stream().map(ParkingLot::getId).anyMatch(Predicate.isEqual(id))
В дополнение к ответу Алексиса С. Если вы работаете со списком массивов, в котором вы не уверены, существует ли элемент, который вы ищете, используйте это.
Тогда вы могли бы просто проверить , является ли это .
null
источник
источник
Улучшенный однострочный ответ: если вы ищете логическое возвращаемое значение, мы можем сделать это лучше, добавив isPresent:
источник