JavaRush /Java блог /Random /Кофе-брейк #250. Как в Java Stream API использовать .coll...

Кофе-брейк #250. Как в Java Stream API использовать .collect и .sorted. Понимание Lombok в Java за 3 минуты

Статья из группы Random

Как в Java Stream API использовать .collect и .sorted

Источник: Medium В этом руководстве показаны два практических примера использования методов Stream API: .collect() и .sorted(). Применяя их, разработчик может значительно упростить сортировку по заданным параметрам. Потоковые операции позволяют разработчикам Java выполнять задачи с легкостью и элегантностью. Разумеется, это относится также к сортировке и обработке объектов. Кофе-брейк #250. Как в Java Stream API использовать .collect и .sorted. Понимание Lombok в Java за 3 минуты - 1

Превращаем 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, то теперь я также могу писать по-другому:

Map<String, Customer> map = customers.stream().collect(Collectors.toMap(Customer::getCustomerId, customer -> customer));
Давайте разберем шаг за шагом показанный выше однострочный код:
  • 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) в результирующей карте.
🤔 Сейчас хороший момент, чтобы остановиться и ответить на следующие два вопроса?
  1. Можете ли вы выписать все записи на карте из приведенного выше примера кода?
  2. У вас есть список 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));
  
    /*
      сортируем список игроков по количеству очков каждого игрока в порядке возрастания. 
      Вставьте свой код ниже:
    */
  }
}
Раньше я для этого использовал List.sort:

players.sort(Comparator.comparingDouble(Player::getScore));
Но поскольку я уже научился работать со Stream, теперь я пишу вот так:

players.stream()
   .sorted(Comparator.comparingDouble(Player::getScore))
   .toList();
Разберем этот код пошагово:
  • .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 этого добивается:
  1. Удаление шума: устраняя повторяющиеся методы getter и setter, конструкторы и другой шаблонный код, Lombok делает определение класса более кратким, фокусируясь на том, что действительно важно.
  2. li><Поощрение неизменяемости: с такими аннотациями, как @Value, Lombok облегчает создание неизменяемых классов, что приводит к более надежному коду.
  3. Упрощение сложных шаблонов. Такие аннотации, как @Builder, создают сложные шаблоны с меньшим количеством кода, упрощают понимание целей класса.
  4. Улучшение создания тестовых данных. В тестовых классах вы можете использовать Lombok для быстрого и четкого создания объектов тестовых данных, что сделает настройку теста более прозрачной.

Заключение

Lombok — это мощный инструмент, который значительно сокращает шаблонный код в проектах Java. Вы можете написать более лаконичный и удобный для сопровождения код, если поймете его ключевые функции и настроите Lombok в своей среде разработки. Поэкспериментируйте с его различными аннотациями и посмотрите, как они могут преобразовать вашу кодовую базу.
Комментарии (1)
ЧТОБЫ ПОСМОТРЕТЬ ВСЕ КОММЕНТАРИИ ИЛИ ОСТАВИТЬ КОММЕНТАРИЙ,
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ
Anton Folko Уровень 1
20 февраля 2024

 эта часть кода создает Comparator, используя метод comparingDouble класса Comparator
Comparator - это интерфейс. Спасибо за статью, помогла освежить использование sorted(). Кст вы не указали, что можно и без компаратора, тогда будет применена естественная сортировка.