Мы все широко использовали классы Collection, такие как List, Map и их производные версии. И каждый раз, когда мы использовали их, нам приходилось перебирать их, чтобы либо найти какой-то элемент, либо обновить элементы, либо найти разные элементы, соответствующие некоторому условию. Рассмотрим список лиц, как показано ниже:
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, мы бы сделали:
List<Person> olderThan30OldWay = new ArrayList<>(); for ( Person p : personList){ if ( p.age >= 30){ olderThan30OldWay.add(p); } } System.out.println(olderThan30OldWay);
и это дает мне вывод как:
[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, позвольте мне показать код, эквивалентный первому примеру кода:
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);
Приведенный выше код использует как внутреннюю итерацию, так и лямбда-выражения, чтобы сделать его интуитивно понятным, лаконичным и приятным для глаз.
Если вы не знакомы с идеей лямбда-выражений, ознакомьтесь с моей предыдущей записью, в которой кратко описываются лямбда-выражения.