🛒 Collectors: Собираем урожай Stream API
Мы отфильтровали, преобразовали и отсортировали данные. Теперь их нужно сложить в коробочку, чтобы использовать дальше. Для этого существует терминальная операция
Внутрь нее мы передаем специальный объект - Collector. Чтобы не писать его вручную, в Java есть утилитный класс
📦 Базовый набор (Must Have)
1. В список или множество
💙
💙
💙 Java 16+ Update: Теперь можно просто писать
2. В строку (
💙 Больше не нужно мучиться с
💙
🔑 Продвинутый уровень: Карты и Группировки
Самая мощная магия происходит здесь.
3. В Map (
Превращает список объектов в Map (ключ-значение).
💙 Синтаксис:
💙 Важно: Если ключи совпадут, вылетит
💙 Лечение: Третий аргумент - "мердж-функция" (что делать при конфликте).
4. Группировка (
Аналог
💙 Разделяет элементы на группы по какому-то признаку и кладет их в
💻 Примеры в коде
Представьте, у нас есть класс
⚡ Полезный лайфхак
В
🔥 Итог
#Java #StreamAPI #Collectors #JavaTips
📲 Мы в MAX
👉@BookJava
Мы отфильтровали, преобразовали и отсортировали данные. Теперь их нужно сложить в коробочку, чтобы использовать дальше. Для этого существует терминальная операция
.collect().Внутрь нее мы передаем специальный объект - Collector. Чтобы не писать его вручную, в Java есть утилитный класс
Collectors с готовыми решениями на все случаи жизни.📦 Базовый набор (Must Have)
1. В список или множество
Collectors.toList() - собирает все в ArrayList (но тип не гарантирован).Collectors.toSet() - собирает в HashSet (убирает дубликаты)..toList() прямо у стрима, без collect(...). Это создает неизменяемый список.2. В строку (
joining)StringBuilder в циклах.Collectors.joining(", ") - склеит строки через запятую.🔑 Продвинутый уровень: Карты и Группировки
Самая мощная магия происходит здесь.
3. В Map (
toMap)Превращает список объектов в Map (ключ-значение).
toMap(Function keyMapper, Function valueMapper)IllegalStateException.4. Группировка (
groupingBy)Аналог
GROUP BY из SQL. Это киллер-фича Stream API.Map<Критерий, Список>.💻 Примеры в коде
Представьте, у нас есть класс
User(String name, String role).
List<User> users = List.of(
new User("Alex", "ADMIN"),
new User("Bob", "USER"),
new User("Charlie", "USER")
);
// 1. Склеиваем имена в одну строку
String names = users.stream()
.map(User::getName)
.collect(Collectors.joining(", "));
// Результат: "Alex, Bob, Charlie"
// 2. Превращаем в Map: Имя -> Роль
Map<String, String> userMap = users.stream()
.collect(Collectors.toMap(
User::getName, // Ключ
User::getRole // Значение
));
// Результат: {Alex=ADMIN, Bob=USER, Charlie=USER}
// 3. Группируем по Роли (SQL GROUP BY)
Map<String, List<User>> byRole = users.stream()
.collect(Collectors.groupingBy(User::getRole));
// Результат:
// {
// "ADMIN": [User(Alex)],
// "USER": [User(Bob), User(Charlie)]
// }
⚡ Полезный лайфхак
В
groupingBy можно передать второй коллектор! Например, чтобы не просто сгруппировать пользователей, а сразу посчитать их количество в каждой группе:
Map<String, Long> countByRole = users.stream()
.collect(Collectors.groupingBy(
User::getRole,
Collectors.counting() // Downstream collector
));
// Результат: {ADMIN=1, USER=2}
🔥 Итог
Collectors позволяют превратить поток данных в любую удобную структуру: от простого списка до сложной многоуровневой мапы.#Java #StreamAPI #Collectors #JavaTips
👉@BookJava
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥5
🎁 Optional: Лекарство от NullPointerException
Тони Хоар назвал изобретение
В Java 8 появился
📦 Что внутри?
Представьте
🔴 В ней может лежать объект (Non-empty).
🔴 Или она может быть пустой (Empty).
Главное правило: Никогда не возвращайте
🚫 Как делать НЕ надо
Самая частая ошибка новичка, использовать
Метод
✅ Как делать НАДО (Functional Style)
Вся мощь
1. Если значение есть, сделай что-то (
2. Если значения нет, верни дефолт (
3. Если значения нет — брось ошибку (
4. Преобразование внутри коробки (
Допустим, нам нужен не сам юзер, а его email. Если юзера нет, то и email нет.
⚡ Золотые правила использования
1. Только для возвращаемых значений! Не используйте
2.
🔴
🔴
🔥 Итог
Забудьте про
#Java #Optional #CleanCode #NoMoreNPE
📲 Мы в MAX
👉@BookJava
Тони Хоар назвал изобретение
null своей "ошибкой на миллиард долларов". NullPointerException (NPE) - самый частый кошмар Java-разработчика.В Java 8 появился
Optional<T> - класс-обертка, который явно говорит: "Здесь значения может и не быть".📦 Что внутри?
Представьте
Optional как коробку.Главное правило: Никогда не возвращайте
null из метода, если можно вернуть Optional.empty().🚫 Как делать НЕ надо
Самая частая ошибка новичка, использовать
Optional как старый добрый if (x != null):
Optional<User> userOpt = findUser("Alex");
// ❌ ПЛОХО: Это тот же null-check, только сложнее
if (userOpt.isPresent()) {
System.out.println(userOpt.get().getName());
}
Метод
.get() - это зло. Если коробка пуста, он бросит NoSuchElementException, и вы просто поменяли шило (NPE) на мыло.✅ Как делать НАДО (Functional Style)
Вся мощь
Optional раскрывается, когда вы строите цепочки вызовов, как в стримах.1. Если значение есть, сделай что-то (
ifPresent)
findUser("Alex").ifPresent(user -> System.out.println(user.getName()));
2. Если значения нет, верни дефолт (
orElse)
// Вернет юзера или создаст нового "Guest", если не нашел
User user = findUser("Alex").orElse(new User("Guest"));
3. Если значения нет — брось ошибку (
orElseThrow)
User user = findUser("Alex")
.orElseThrow(() -> new IllegalArgumentException("User not found"));
4. Преобразование внутри коробки (
map)Допустим, нам нужен не сам юзер, а его email. Если юзера нет, то и email нет.
String email = findUser("Alex")
.map(User::getEmail) // Достаем email (если юзер есть)
.map(String::toUpperCase) // В верхний регистр (если email был)
.orElse("UNKNOWN"); // Если хоть на одном этапе было пусто
⚡ Золотые правила использования
1. Только для возвращаемых значений! Не используйте
Optional как тип поля в классе или аргумент метода. Это лишний оверхед и мусор в коде.2.
orElse() vs orElseGet():orElse(new Object()) - объект создается всегда, даже если он не нужен.orElseGet(() -> new Object()) - объект создается только если в коробке пусто (лениво). Используйте этот вариант для тяжелых объектов.🔥 Итог
Optional спасает не тем, что убирает null, а тем, что заставляет вас явно обработать случай отсутствия значения.Забудьте про
.get(). Используйте .map(), .filter() и .orElse().#Java #Optional #CleanCode #NoMoreNPE
👉@BookJava
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6❤4🔥2