Мы все широко использовали классы Collection, такие как List, Map и их производные версии. И каждый раз, когда мы использовали их, нам приходилось перебирать их, чтобы либо найти какой-то элемент, либо обновить элементы, либо найти разные элементы, соответствующие некоторому условию. Рассмотрим список лиц, как показано ниже:
1
2
3
4
5
|
List<Person> personList = new ArrayList<>(); personList.add( new Person( 'Virat' , 'Kohli' , 22 )); personList.add( new Person( 'Arun' , 'Kumar' , 25 )); personList.add( new Person( 'Rajesh' , 'Mohan' , 32 )); personList.add( new Person( 'Rahul' , 'Dravid' , 35 )); |
Чтобы узнать все экземпляры Person с возрастом более 30, мы бы сделали:
1
2
3
4
5
6
7
|
List<Person> olderThan30OldWay = new ArrayList<>(); for ( Person p : personList){ if ( p.age >= 30 ){ olderThan30OldWay.add(p); } } System.out.println(olderThan30OldWay); |
и это дает мне вывод как:
1
|
[Rajesh Mohan, 32, Rahul Dravid, 35] |
Код легко написать, но не более ли он многословен, особенно часть итерации? Почему мы должны повторяться? Не было бы здорово, если бы существовал API, который итерировал бы содержимое и давал бы нам конечный результат, то есть мы даем исходный список и используем серию вызовов методов, чтобы получить нам искомый искомый список. Да, это возможно в других языках, таких как Scala, Groovy, которые поддерживают проходящие замыкания, а также поддерживают внутреннюю итерацию. Но есть ли решение для разработчиков Java? Да, эта точная проблема решается путем введения поддержки лямбда-выражений (замыканий) и расширенного API-интерфейса Collection для использования поддержки лямбда-выражений. Печальная новость заключается в том, что она станет частью Java 8 и займет некоторое время, чтобы стать основной разработкой.
Использование улучшений Java 8 в вышеупомянутом сценарии
Как я уже говорил, API-интерфейс Collections расширяется для поддержки использования лямбда-выражений, и подробнее об этом можно прочитать здесь . Вместо добавления всех новых API в класс Collection команда JDK создала новую концепцию под названием «Поток» и добавила большинство API в этом классе. «Поток» — это последовательность элементов, полученных из Коллекции, из которой она создана. Чтобы узнать больше о происхождении класса Stream, пожалуйста, обратитесь к этому документу . Для реализации примера, который я начал с использования улучшений в Java 8, мы будем использовать несколько новых API, а именно: stream (), filter (), collect (), Collectors.toCollection ().
stream () : использует коллекцию, в которой вызывается этот API, для создания экземпляра класса Stream .
filter () : этот метод принимает лямбда-выражение, которое принимает один параметр и возвращает логическое значение. Это лямбда-выражение написано как замена для реализации класса Predicate .
collect () : есть 2 перегруженные версии этого метода. Тот, который я использую здесь, берет экземпляр Collector . Этот метод берет содержимое потока и создает другую коллекцию. Эта логика построения определяется Коллектором .
Collectors.toCollection () : Collectors — это фабрика для Collector . И toCollection () принимает ссылку на лямбда-выражение / метод, которая должна возвращать новый экземпляр любых производных класса Collection.
Кратко ознакомившись с используемыми API, позвольте мне показать код, эквивалентный первому примеру кода:
1
2
3
4
5
6
7
8
|
List<Person> olderThan30 = //Create a Stream from the personList personList.stream(). //filter the element to select only those with age >= 30 filter(p -> p.age >= 30 ). //put those filtered elements into a new List. collect(Collectors.toCollection(() -> new ArrayList<Person>())); System.out.println(olderThan30); |
Приведенный выше код использует как внутреннюю итерацию, так и лямбда-выражения, чтобы сделать его интуитивно понятным, лаконичным и приятным для глаз. Если вы не знакомы с идеей лямбда-выражений, ознакомьтесь с моей предыдущей записью, в которой кратко описываются лямбда-выражения.
Ссылка: Извлечение элементов коллекции Java — путь Java 8 от нашего партнера по JCG Мохамеда Санауллы в блоге Experiences Unlimited .