1. Обзор
Поиск различных элементов в списке-одна из распространенных задач, с которой мы, программисты, обычно сталкиваемся. Начиная с Java 8 с включением Streams у нас есть новый API для обработки данных с использованием функционального подхода.
В этой статье мы покажем различные альтернативы фильтрации коллекции с использованием определенного атрибута объектов в списке.
2. Использование API потока
API потока предоставляет метод distinct() , который возвращает различные элементы списка на основе метода equals() класса Object .
Однако он становится менее гибким, если мы хотим фильтровать по определенному атрибуту. Одна из альтернатив, которые у нас есть, – это написать фильтр, который поддерживает состояние.
2.1. Использование фильтра с отслеживанием состояния
Одним из возможных решений было бы реализовать предикат с сохранением состояния :
public staticPredicate distinctByKey( Function super T, ?> keyExtractor) { Map
Чтобы проверить это, мы будем использовать следующий Person класс, который имеет атрибуты возраст , электронная почта и имя:
public class Person { private int age; private String name; private String email; // standard getters and setters }
И чтобы получить новую отфильтрованную коллекцию по имени , мы можем использовать:
ListpersonListFiltered = personList.stream() .filter(distinctByKey(p -> p.getName())) .collect(Collectors.toList());
3. Использование коллекций Eclipse
Eclipse Collections – это библиотека, которая предоставляет дополнительные методы для обработки Потоков и коллекций в Java.
3.1. Использование списка Iterate.distinct()
Метод List Iterate.distinct() позволяет нам фильтровать Поток , используя различные стратегии хеширования. Эти стратегии могут быть определены с помощью лямбда-выражений или ссылок на методы.
Если мы хотим отфильтровать по имени Человека :
ListpersonListFiltered = ListIterate .distinct(personList, HashingStrategies.fromFunction(Person::getName));
Или, если атрибут, который мы собираемся использовать, является примитивным (int, long, double), мы можем использовать специализированную функцию, подобную этой:
ListpersonListFiltered = ListIterate.distinct( personList, HashingStrategies.fromIntFunction(Person::getAge));
3.2. Зависимость Maven
Нам нужно добавить следующие зависимости в ваш pom.xml использовать коллекции Eclipse в нашем проекте:
org.eclipse.collections eclipse-collections 8.2.0
Вы можете найти последнюю версию библиотеки коллекций Eclipse в репозитории Maven Central .
Чтобы узнать больше об этой библиотеке, мы можем перейти к этой статье .
4. Использование Vavr (Javaslang)
Это функциональная библиотека для Java 8, которая предоставляет неизменяемые данные и функциональные структуры управления.
4.1. Использование List.DistinctBy
Для фильтрации списков этот класс предоставляет свой собственный класс List, который имеет метод DistinctBy () , который позволяет нам фильтровать по атрибутам объектов, которые он содержит:
ListpersonListFiltered = List.ofAll(personList) .distinctBy(Person::getName) .toJavaList();
4.2. Зависимость Maven
Мы добавим следующие зависимости в ваш pom.xml использовать Var в нашем проекте.
io.vavr vavr 0.9.0
Вы можете найти последнюю версию библиотеки Var в репозитории Maven Central .
Чтобы узнать больше об этой библиотеке, мы можем перейти к этой статье .
5. Использование Streamyx
Эта библиотека предоставляет полезные классы и методы для обработки потоков Java 8.
5.1. Использование Streamyx.distinct
В предоставленных классах есть Streamyx , который имеет метод distinct , которому мы можем отправить ссылку на атрибут, в котором мы хотим различать:
ListpersonListFiltered = StreamEx.of(personList) .distinct(Person::getName) .toList();
5.2. Зависимость Maven
Мы добавим следующие зависимости в ваш pom.xml использовать Streamyx в нашем проекте.
one.util streamex 0.6.5
Вы можете найти последнюю версию библиотеки StreamEx в репозитории Maven Central .
6. Заключение
В этом кратком руководстве мы рассмотрели примеры того, как получить различные элементы потока на основе атрибута, используя стандартный API Java 8 и дополнительные альтернативы с другими библиотеками.
Как всегда, полный код доступен на GitHub .