Как в Java Stream API использовать .collect и .sorted
Источник: MediumВ этом руководстве показаны два практических примера использования методов Stream API: .collect() и .sorted(). Применяя их, разработчик может значительно упростить сортировку по заданным параметрам.
Потоковые операции позволяют разработчикам Java выполнять задачи с легкостью и элегантностью. Разумеется, это относится также к сортировке и обработке объектов.
Превращаем List в Map, используя .collect
Например, у нас есть список Customer, и у каждого Customer есть поле с именем customerId. Наша цель состоит в том, чтобы создать Map, которая использует customerId в качестве ключа и ссылку на объект Customer в качестве значения.
class Customer {
private String customerId;
public Customer(String id){ this.customerId = id; }
public String getCustomerId(){ return this.customerId; }
}
class Example {
public static void main(String[] args){
List<Customer> customers = new ArrayList<>();
customers.add(new Customer("001"))
customers.add(new Customer("002"));
/*
создать map, которая использует customerId в качестве key
и ссылку на объект Customer в качестве value. Вставьте свой код ниже:
*/
}
}
Раньше я писал вот так:
Map<String, Customer> map = new HashMap<>();
for(Customer c : customers){
map.putIfAbsent(c.getCustomerId(), c);
}
Но так как я научился использовать Stream API, то теперь я также могу писать по-другому:
Давайте разберем шаг за шагом показанный выше однострочный код:
customers.stream() — метод stream() вызывается в списке customers, который преобразует его в поток. Поток (Stream) — это последовательность элементов, которые можно обрабатывать последовательно или параллельно с помощью потоковых операций.
.collect(Collectors.toMap(Customer::getCustomerId, customer -> customer)) — .collect является терминальной операцией в Java 8 Stream API. В этом примере элементы потока собираются в карту (map) с помощью коллектора (сборщика) toMap.
Customer::getCustomerId — это ссылка на метод, которая относится к методу getCustomerId() класса Customer. Она используется в качестве средства сопоставления ключей (key mapper) для коллектора toMap, то есть извлекает customerId из каждого объекта Customer для использования в качестве ключа в результирующей карте.
customer -> customer — это лямбда-выражение представляет сопоставитель значений (value mapper) для коллектора toMap. Оно указывает, что исходный объект Customer должен использоваться в качестве значения (value) в результирующей карте.
🤔 Сейчас хороший момент, чтобы остановиться и ответить на следующие два вопроса?
Можете ли вы выписать все записи на карте из приведенного выше примера кода?
У вас есть список Recipe и у каждого Recipe есть поле recipeName. Можете ли вы использовать .collect для создания карты с ключом recipeName и ссылкой на объект Recipe в качестве значения?
Сортировка списка объектов с помощью .sorted
Существует список игроков (players), и у каждого Player есть поле с именем score (очки). Поле score двойное (double). Наша цель состоит в том, чтобы отсортировать список по количеству очков каждого игрока в порядке возрастания.
class Player {
private String id;
private double score;
public Player(String id, double score){ ... }
public double getScore(){return this.score; }
}
class Example2 {
public static void main(String[] args){
List<Player> players = new ArrayList<>();
players.add(new Player("001", 89.3));
players.add(new Player("002", 79.8));
/*
сортируем список игроков по количеству очков каждого игрока в порядке возрастания.
Вставьте свой код ниже:
*/
}
}
.stream() — метод stream() вызывается для коллекции players, которая преобразует ее в поток. Поток (Stream) — это последовательность элементов, которые можно обрабатывать последовательно или параллельно с помощью потоковых операций.
.sorted(Comparator.comparingDouble(Player::getScore)) — метод sorted вызывается в потоке для сортировки элементов на основе поля score объекта Player. Этот метод требует Comparator, чтобы определить порядок сортировки.
Comparator.comparingDouble(Player::getScore) — эта часть кода создает Comparator, используя метод comparingDouble класса Comparator. Метод comparingDouble принимает функцию в качестве аргумента, и в этом случае мы используем ссылку на метод Player::getScore. Это означает, что мы сравниваем объекты Player на основе их поля score, которое должно иметь тип double.
.toList() — эта терминальная операция собирает элементы отсортированного потока в список.
После выполнения всех операций с потоком конечным результатом является новый список, содержащий элементы коллекции игроков, отсортированные в порядке возрастания на основе поля score каждого объекта Player.
Понимание Lombok в Java за 3 минуты
Источник: MediumИзучив эту публикацию, вы поймете предназначение и основные принципы работы проекта Lombok в Java.
Что такое Lombok?
Шаблонный код является широко распространенной проблемой в Java-разработке. При написании геттеров и сеттеров, реализации методов equals() и hashCode(), повторяющийся код может загромождать ваши классы и усложнять их поддержку. И вот здесь Lombok может все изменить в лучшую сторону.
Project Lombok — это библиотека Java, которая помогает разработчикам избавиться от большей части шаблонного кода с помощью простых аннотаций. Он работает как препроцессор кода на этапе компиляции, заменяя аннотации соответствующим кодом. В результате получается более краткая, удобочитаемая и удобная кодовая база.
Ключевые особенности и аннотации Lombok
Lombok предлагает множество фич, которые упрощают общие задачи программирования на Java. Вот некоторые из ключевых аннотаций, которые могут оказаться полезными:
@Getter и @Setter — эти аннотации автоматически генерируют методы getter и setter для полей, что позволяет вам взаимодействовать с ними без ручного написания этих методов.
@ToString — с помощью этой аннотации вы можете автоматически создать метод toString(), включающий все поля вашего класса.
@EqualsAndHashCode — эта аннотация генерирует методы equals() и hashCode() с учетом всех нестатических полей.
@NoArgsConstructor, @RequiredArgsConstructor и @AllArgsConstructor — эти аннотации генерируют конструкторы с разными уровнями аргументов, уменьшая необходимость их написания вручную.
@Data — комплексная аннотация, включающая @Getter, @Setter, @ToString, @EqualsAndHashCode и конструктор. По существу она объединяет наиболее распространенные функции в одной аннотации.
@Builder — включает шаблон builder для вашего класса, позволяя создавать более читаемые и гибкие экземпляры.
@SneakyThrows — позволяет обрабатывать проверенные исключения, не объявляя их в сигнатуре метода.
Это всего лишь несколько примеров того, что предлагает Lombok. Существует множество других аннотаций и возможностей, которые вы можете изучить в зависимости от ваших конкретных потребностей.
Настройка Lombok в IntelliJ IDEA
Интеграция Lombok в вашу IntelliJ IDEA — это очень простой процесс. Чтобы начать, выполните следующие действия:
1. Добавьте Lombok в качестве зависимости:
Включите Lombok в свой проект, добавив следующую зависимость Maven:
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.28</version> <! - Use the latest version >
<scope>provided</scope>
</dependency>
2. Установите плагин Lombok:
В IntelliJ IDEA перейдите по элементам меню File -> Settings (для Mac: IntelliJ IDEA -> Preferences) -> Plugins и найдите “Lombok”. Нажмите кнопку “Install” рядом с подключаемым модулем и перезапустите IntelliJ IDEA для активации.
3. Включите обработку аннотаций:
Перейдите по элементам меню File -> Settings -> Build, Execution, Deployment -> Compiler -> Annotation Processors и установите флажок “Enable annotation processing” (Включить обработку аннотаций).
Теперь Lombok полностью настроен в вашей IntelliJ IDEA, и вы можете начать использовать его аннотации в своих классах Java.
Пример сокращения кода с помощью @Getter, @Setter и так далее
Аннотации Lombok, такие как @Getter, @Setter, @AllArgsConstructor и другие, способны значительно сократить объем шаблонного кода в ваших тестовых классах. Вот пример до и после применения Lombok:
public class User {
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
// Дополнительный шаблонный код для конструкторов, equals, hashCode и так далее.
}
А теперь код с Lombok:
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
public class User {
private String name;
private int age;
}
Повышение читабельности кода
Использование Lombok не просто минимизирует код — он значительно повышает читаемость кода. Вот несколько способов, благодаря которым Lombok этого добивается:
Удаление шума: устраняя повторяющиеся методы getter и setter, конструкторы и другой шаблонный код, Lombok делает определение класса более кратким, фокусируясь на том, что действительно важно.
li><Поощрение неизменяемости: с такими аннотациями, как @Value, Lombok облегчает создание неизменяемых классов, что приводит к более надежному коду.
Упрощение сложных шаблонов. Такие аннотации, как @Builder, создают сложные шаблоны с меньшим количеством кода, упрощают понимание целей класса.
Улучшение создания тестовых данных. В тестовых классах вы можете использовать Lombok для быстрого и четкого создания объектов тестовых данных, что сделает настройку теста более прозрачной.
Заключение
Lombok — это мощный инструмент, который значительно сокращает шаблонный код в проектах Java. Вы можете написать более лаконичный и удобный для сопровождения код, если поймете его ключевые функции и настроите Lombok в своей среде разработки. Поэкспериментируйте с его различными аннотациями и посмотрите, как они могут преобразовать вашу кодовую базу.
эта часть кода создает Comparator, используя метод comparingDouble класса Comparator
Comparator - это интерфейс.
Спасибо за статью, помогла освежить использование sorted(). Кст вы не указали, что можно и без компаратора, тогда будет применена естественная сортировка.
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ