Использование метода String.join
Метод String.join можно использовать для объединения строк с заданным разделителем.
📲 Мы в MAX
👉@BookJava
Метод String.join можно использовать для объединения строк с заданным разделителем.
List<String> items = Arrays.asList("Apple", "Banana", "Cherry");
String result = String.join(", ", items);
System.out.println(result); // Output: Apple, Banana, Cherry
📲 Мы в MAX
👉@BookJava
❤2👍2
☕ Функциональные интерфейсы: Магия за кулисами Лямбд
Если вы используете лямбды (а вы наверняка их используете), значит, вы работаете с функциональными интерфейсами. Давайте разберем, что это такое, зачем нужна аннотация и какие интерфейсы вы обязаны знать наизусть.
🎯 Что это такое?
Функциональный интерфейс - это интерфейс, который содержит ровно один абстрактный метод.
Именно это ограничение позволяет компилятору превращать лямбда-выражение в экземпляр этого интерфейса.
💙 Примечание: В интерфейсе может быть сколько угодно
📝 Аннотация
Ставить её над интерфейсом не обязательно, но хорошим тоном считается ставить.
Зачем? Она работает как защита от дурака: если вы или ваш коллега случайно добавите второй абстрактный метод в интерфейс, компилятор сразу выдаст ошибку, не дожидаясь падения кода в местах использования лямбд.
🧰 Шпаргалка: "Великолепная четверка"
В пакете
1. Predicate
💙 Что делает: Проверяет условие.
💙 Метод:
💙 Где нужен: Фильтрация стримов (`filter`), проверки.
2. Consumer
💙 Что делает: "Потребляет" объект, ничего не возвращая.
💙 Метод:
💙 Где нужен: Вывод на экран, запись в БД,
3. Supplier
💙 Что делает: "Поставляет" объект (из ниоткуда), ничего не принимая.
💙 Метод:
💙 Где нужен: Ленивая инициализация, генерация значений,
4. Function
💙 Что делает: Превращает объект типа T в объект типа R.
💙 Метод:
💙 Где нужен: Преобразование данных,
💻 Пример в коде
🔥 Итог
Функциональные интерфейсы - это контракт для лямбда-выражений. Используйте стандартные из
#Java #Core #Lambda #FunctionalProgramming
📲 Мы в MAX
👉@BookJava
Если вы используете лямбды (а вы наверняка их используете), значит, вы работаете с функциональными интерфейсами. Давайте разберем, что это такое, зачем нужна аннотация и какие интерфейсы вы обязаны знать наизусть.
🎯 Что это такое?
Функциональный интерфейс - это интерфейс, который содержит ровно один абстрактный метод.
Именно это ограничение позволяет компилятору превращать лямбда-выражение в экземпляр этого интерфейса.
default или static методов. Главное - только один абстрактный.📝 Аннотация
@FunctionalInterfaceСтавить её над интерфейсом не обязательно, но хорошим тоном считается ставить.
Зачем? Она работает как защита от дурака: если вы или ваш коллега случайно добавите второй абстрактный метод в интерфейс, компилятор сразу выдаст ошибку, не дожидаясь падения кода в местах использования лямбд.
🧰 Шпаргалка: "Великолепная четверка"
В пакете
java.util.function уже есть готовые интерфейсы на 99% случаев жизни. Не пишите свои велосипеды, пока не выучите эти:1. Predicate
<T>boolean test(T t)2. Consumer
<T>void accept(T t)forEach.3. Supplier
<T>T get()orElseGet.4. Function
<T, R>R apply(T t)map в стримах.💻 Пример в коде
@FunctionalInterface
interface Converter {
int stringToInt(String s);
}
public class Main {
public static void main(String[] args) {
// 1. Создаем реализацию через лямбду
Converter converter = str -> Integer.parseInt(str);
// 2. Использование стандартного Consumer
java.util.function.Consumer<Integer> print = x -> System.out.println("Result: " + x);
int result = converter.stringToInt("123");
print.accept(result); // Вывод: Result: 123
}
}
🔥 Итог
Функциональные интерфейсы - это контракт для лямбда-выражений. Используйте стандартные из
java.util.function, чтобы ваш код был понятен другим разработчикам без лишних документаций.#Java #Core #Lambda #FunctionalProgramming
👉@BookJava
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥7👍1
🚀 Функциональные интерфейсы: Level Up
В первой части мы разобрали «Великолепную четверку» (
Для этого в Java есть Bi-версии и Операторы.
👯 Семейство «Bi» (Два аргумента)
Стандартные интерфейсы принимают только один параметр. Если вам нужно обработать пару значений (например, ключ и значение из Map), используйте приставку
1. BiPredicate
💙 Метод:
💙 Пример: Проверить, что длина строки
2. BiConsumer
💙 Метод:
💙 Пример:
3. BiFunction
💙 Метод:
💙 Пример: Сложить число
🔄 Семейство «Operator» (Один и тот же тип)
Часто бывает, что вы преобразуете объект, не меняя его тип (String -> String, int -> int). Писать
1. UnaryOperator
💙 Наследник
💙 Пример:
2. BinaryOperator
💙 Наследник
💙 Пример:
⚡ Осторожно с боксингом!
Дженерики (
Для примитивов есть свои спецназовцы:
💙
💙 Правило: Если работаете с числами - всегда ищите примитивный аналог интерфейса.
💻 Пример в коде
🔥 Итог
💙 Нужно 2 аргумента? Ищите Bi.
💙 Тип входа и выхода совпадает? Ищите Operator.
💙 Работаете с
#Java #AdvancedJava #FunctionalProgramming
📲 Мы в MAX
👉@BookJava
В первой части мы разобрали «Великолепную четверку» (
Predicate, Consumer, Supplier, Function). Но что делать, если нужно принять два аргумента? Или если тип входа и выхода совпадает, и лень писать лишний код?Для этого в Java есть Bi-версии и Операторы.
👯 Семейство «Bi» (Два аргумента)
Стандартные интерфейсы принимают только один параметр. Если вам нужно обработать пару значений (например, ключ и значение из Map), используйте приставку
Bi.1. BiPredicate
<T, U>boolean test(T t, U u)T больше числа U.2. BiConsumer
<T, U>void accept(T t, U u)map.forEach((k, v) -> ...) - классический пример использования.3. BiFunction
<T, U, R>R apply(T t, U u)T и число U, получить результат R.🔄 Семейство «Operator» (Один и тот же тип)
Часто бывает, что вы преобразуете объект, не меняя его тип (String -> String, int -> int). Писать
Function<String, String> - слишком длинно.1. UnaryOperator
<T>Function<T, T>.str -> str.toUpperCase() (принимает строку, возвращает строку).2. BinaryOperator
<T>BiFunction<T, T, T>.(a, b) -> a + b (два числа на вход, одно число на выход). Именно он используется в Stream.reduce.⚡ Осторожно с боксингом!
Дженерики (
<T>) работают только с объектами. Если вы используете Function<Integer, Integer> для математики, Java будет постоянно распаковывать и запаковывать int в Integer, что бьет по производительности.Для примитивов есть свои спецназовцы:
IntPredicate, LongConsumer, DoubleFunction и т.д.💻 Пример в коде
import java.util.function.*;
public class AdvancedLambdas {
public static void main(String[] args) {
// 1. BinaryOperator: объединяем две строки
BinaryOperator<String> concat = (s1, s2) -> s1 + " " + s2;
System.out.println(concat.apply("Hello", "Java"));
// 2. BiPredicate: проверяем, начинается ли строка с префикса
BiPredicate<String, String> startsWith = (str, prefix) -> str.startsWith(prefix);
System.out.println(startsWith.test("Telegram", "Tele")); // true
// 3. IntUnaryOperator: работаем с примитивами без лишних объектов
IntUnaryOperator square = x -> x * x;
System.out.println(square.applyAsInt(5)); // 25
}
}
🔥 Итог
int/long/double? Ищите интерфейсы с префиксом типа.#Java #AdvancedJava #FunctionalProgramming
👉@BookJava
Please open Telegram to view this post
VIEW IN TELEGRAM
❤6
🍒 Магия двойного двоеточия: Method References
Мы уже научились писать лямбды. Но иногда даже лямбда кажется слишком громоздкой. Если ваша лямбда не делает ничего, кроме вызова одного уже существующего метода, Java позволяет использовать Method Reference (ссылку на метод).
Синтаксис простой:
🛠 4 ситуации, когда это работает
Есть 4 основных способа использовать оператор
1. Ссылка на статический метод
💙 Лямбда:
💙 Reference:
💙 Суть: Просто перенаправляем входящий параметр в статический метод.
2. Ссылка на метод конкретного объекта
💙 Лямбда:
💙 Reference:
💙 Суть: У нас уже есть готовый объект (System.out), и мы вызываем его метод для каждого элемента.
3. Ссылка на метод произвольного объекта определенного типа (Самый хитрый пункт! 🤯)
💙 Лямбда:
💙 Reference:
💙 Суть: Здесь метод вызывается у самого объекта, который пришел в лямбду. Хотя синтаксис похож на статический вызов, это вызов инстанс-метода.
4. Ссылка на конструктор
💙 Лямбда:
💙 Reference:
💙 Суть: Используется для создания новых объектов (часто в Stream API:
💻 Пример: Было vs Стало
Смотрите, как очищается код. Допустим, у нас есть список имен:
🧠 Как понять, когда использовать?
Если ваша лямбда выглядит так:
или
...смело меняйте её на
Но! Если вам нужно изменить аргумент перед передачей (например,
#Java #CleanCode #MethodReference
📲 Мы в MAX
👉@BookJava
Мы уже научились писать лямбды. Но иногда даже лямбда кажется слишком громоздкой. Если ваша лямбда не делает ничего, кроме вызова одного уже существующего метода, Java позволяет использовать Method Reference (ссылку на метод).
Синтаксис простой:
Класс::метод (без скобок!).🛠 4 ситуации, когда это работает
Есть 4 основных способа использовать оператор
::. Важно понимать разницу, чтобы не путаться.1. Ссылка на статический метод
s -> Integer.parseInt(s)Integer::parseInt2. Ссылка на метод конкретного объекта
obj -> System.out.println(obj)System.out::println3. Ссылка на метод произвольного объекта определенного типа (Самый хитрый пункт! 🤯)
s -> s.toLowerCase()String::toLowerCase4. Ссылка на конструктор
() -> new ArrayList<>()ArrayList::newCollectors.toCollection(ArrayList::new)).💻 Пример: Было vs Стало
Смотрите, как очищается код. Допустим, у нас есть список имен:
List<String> names = Arrays.asList("Alex", "Bob", "Anna");
// ❌ Уровень 1: Анонимный класс (Олдскул)
names.forEach(new Consumer<String>() {
@Override
public void accept(String s) {
System.out.println(s);
}
});
// ⚠️ Уровень 2: Обычная лямбда
names.forEach(s -> System.out.println(s));
// ✅ Уровень 3: Method Reference (Красота)
names.forEach(System.out::println);
🧠 Как понять, когда использовать?
Если ваша лямбда выглядит так:
x -> Class.method(x)или
x -> x.method()...смело меняйте её на
::.Но! Если вам нужно изменить аргумент перед передачей (например,
x -> System.out.println("Name: " + x)), то Method Reference уже не подойдет, оставайтесь на лямбде.#Java #CleanCode #MethodReference
👉@BookJava
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5❤3
Media is too big
VIEW IN TELEGRAM
Spring Boot Tutorial | Полный курс
В этом учебном пособии по Spring Boot рассказывается о том, как начать работу с Spring Boot и Java.
00:00 Intro
01:00 Quick Word
02:12 Spring Boot Overview
03:44 Project Overview
04:28 Spring Initializr
08:05 IntelliJ
10:29 Starting The Server
14:03 Simple API with Spring Boot
18:06 Student Class
23:19 API Layer
26:38 Business Layer
29:08 Dependency Injection
32:47 Properties file
36:15 Creating and Connecting to Database
39:48 JPA and @ Entity
42:35 JPA in Action
45:52 Amigoscode Database Courses
47:35 JPA Repository
52:20 Saving Students
58:49 @ Transient
01:03:01 Post Mapping
01:08:00 Writing Business Logic
01:12:43 Testing Post Request
01:15:35 Deleting Students
01:21:33 Exercise
01:22:53 Solution
01:26:54 Testing
01:29:41 Packaging and Running Application
01:34:52 Next steps
источник
📲 Мы в MAX
👉@BookJava
В этом учебном пособии по Spring Boot рассказывается о том, как начать работу с Spring Boot и Java.
00:00 Intro
01:00 Quick Word
02:12 Spring Boot Overview
03:44 Project Overview
04:28 Spring Initializr
08:05 IntelliJ
10:29 Starting The Server
14:03 Simple API with Spring Boot
18:06 Student Class
23:19 API Layer
26:38 Business Layer
29:08 Dependency Injection
32:47 Properties file
36:15 Creating and Connecting to Database
39:48 JPA and @ Entity
42:35 JPA in Action
45:52 Amigoscode Database Courses
47:35 JPA Repository
52:20 Saving Students
58:49 @ Transient
01:03:01 Post Mapping
01:08:00 Writing Business Logic
01:12:43 Testing Post Request
01:15:35 Deleting Students
01:21:33 Exercise
01:22:53 Solution
01:26:54 Testing
01:29:41 Packaging and Running Application
01:34:52 Next steps
источник
👉@BookJava
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4
This media is not supported in your browser
VIEW IN TELEGRAM
This media is not supported in your browser
VIEW IN TELEGRAM
This media is not supported in your browser
VIEW IN TELEGRAM
This media is not supported in your browser
VIEW IN TELEGRAM
This media is not supported in your browser
VIEW IN TELEGRAM
This media is not supported in your browser
VIEW IN TELEGRAM
This media is not supported in your browser
VIEW IN TELEGRAM
This media is not supported in your browser
VIEW IN TELEGRAM
This media is not supported in your browser
VIEW IN TELEGRAM
This media is not supported in your browser
VIEW IN TELEGRAM
Вопросы-ответы собеседования
Можно ли создать экземпляр абстрактного класса?
Что такое интерфейс?
Как вызвать нестатический метод в статическом?
Чем отличаются параметры от аргументов в методе?
Что такое конструктор? Как его создать и вызвать?
Что такое параметризованный конструктор?
Что такое конструктор по умолчанию?
Что такое приватный конструктор? Зачем он закрытый?
Что такое статическая переменная? Как работает static поле?
Что такое статический метод? Как вызвать static метод?
источник
📲 Мы в MAX
👉@BookJava
Можно ли создать экземпляр абстрактного класса?
Что такое интерфейс?
Как вызвать нестатический метод в статическом?
Чем отличаются параметры от аргументов в методе?
Что такое конструктор? Как его создать и вызвать?
Что такое параметризованный конструктор?
Что такое конструктор по умолчанию?
Что такое приватный конструктор? Зачем он закрытый?
Что такое статическая переменная? Как работает static поле?
Что такое статический метод? Как вызвать static метод?
источник
👉@BookJava
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
❤7👍2🤡1
🗺
Оба метода находятся в конвейере (
1️⃣
Самый простой случай. Вы берете элемент, делаете с ним что-то и возвращаете один измененный элемент. Структура потока не меняется.
💙 Логика:
💙 Пример: Есть список сотрудников (
💙 Аналогия: У вас есть коробка с яблоками. Вы берете каждое яблоко, чистите его и кладете обратно. В итоге у вас столько же объектов, просто они изменились.
2️⃣
Этот метод нужен, когда элементы стрима - это контейнеры (списки, массивы), и вам нужно достать содержимое наружу, "сплющив" всё в один поток.
💙 Логика:
💙 Пример: Есть список отделов (
💙 Аналогия: У вас есть коробка, внутри которой лежат маленькие коробочки с конфетами.
💙 Если сделать
💙 Если сделать
💻 Код: Почувствуйте разницу
Допустим, у нас есть "Списков списков":
❌ Попытка с
✅ Решение с
⚡ Когда что использовать?
1.
2.
💙
💙 Работа с файлами (список строк из списка файлов).
💙 Работа с
🔥 Итог
💙
💙
#Java #StreamAPI #MapVsFlatMap #InterviewQuestions
📲 Мы в MAX
👉@BookJava
map() vs flatMap(): Битва трансформеровОба метода находятся в конвейере (
Intermediate operations) и нужны для преобразования данных. Но работают они с разной геометрией.1️⃣
map() - Один к одному (1:1)Самый простой случай. Вы берете элемент, делаете с ним что-то и возвращаете один измененный элемент. Структура потока не меняется.
Employee), нужно получить список их имен (String).
stream.map(employee -> employee.getName()) // Был Employee, стал String
2️⃣
flatMap() - Один ко многим (1:N) + СплющиваниеЭтот метод нужен, когда элементы стрима - это контейнеры (списки, массивы), и вам нужно достать содержимое наружу, "сплющив" всё в один поток.
Department), в каждом отделе - список сотрудников (List<Employee>). Вы хотите получить один общий список всех сотрудников компании.map, у вас будет поток коробочек.flatMap, вы высыпаете конфеты из всех коробочек в одну большую кучу.💻 Код: Почувствуйте разницу
Допустим, у нас есть "Списков списков":
List<List<String>> nestedList = List.of(List.of("A", "B"), List.of("C", "D"));❌ Попытка с
map:
// Мы получим Stream из Списков: Stream<List<String>>
nestedList.stream()
.map(list -> list.stream())
.toList();
// Результат: [[A, B], [C, D]] — Матрёшка осталась!
✅ Решение с
flatMap:
// Мы получим единый Stream строк: Stream<String>
nestedList.stream()
.flatMap(list -> list.stream()) // Превращаем каждый список в стрим и сливаем
.toList();
// Результат: [A, B, C, D] — То, что нужно!
⚡ Когда что использовать?
1.
map: Используем в 90% случаев. Когда нужно просто превратить А в Б (Число в Строку, Объект в Поле объекта).2.
flatMap: Используем, когда нужно убрать вложенность.List<List<T>> List<T>Order List<LineItem>.🔥 Итог
map преобразует элементы.flatMap преобразует и разворачивает структуру.#Java #StreamAPI #MapVsFlatMap #InterviewQuestions
👉@BookJava
Please open Telegram to view this post
VIEW IN TELEGRAM
❤9👍6
🚀 В чем разница между
Если вы работаете с Java, то наверняка сталкивались с
1. Синхронизация (Потокобезопасность)
-
- Синхронизирован (потокобезопасен). Все его методы синхронизированы, то есть только один поток может работать с ним одновременно.
- Это делает
-
- Не синхронизирован (не потокобезопасен). Несколько потоков могут обращаться к нему одновременно, что может привести к проблемам в многопоточных средах.
- Для потокобезопасности можно использовать
2. Null-ключи и Null-значения
-
- Не позволяет использовать
-
- Разрешает один
3. Производительность
-
- Медленнее из-за накладных расходов на синхронизацию.
-
- Быстрее в однопоточных средах, так как не синхронизирован.
4. Наследие
-
- Считается устаревшим классом (появился в Java 1.0). Не является частью Java Collections Framework.
-
- Часть Java Collections Framework (появился в Java 1.2). Более современный и широко используемый.
5. Итерация
-
- Использует
-
- Использует
6. Наследование
-
- Наследуется от класса
-
- Наследуется от
7. Рекомендации по использованию
- Используйте
- Работаете в однопоточной среде.
- Нужна высокая производительность.
- Требуется поддержка
- Используйте
- Нужна потокобезопасность в многопоточной среде.
- Однако в современной Java
Пример кода
Итоговая таблица
| Особенность |
|-------------------------|---------------------------------|-------------------------------|
| Синхронизация | Синхронизирован | Не синхронизирован |
| Null-ключи/значения | Запрещены | Разрешены |
| Производительность | Медленнее | Быстрее |
| Наследие | Устаревший (Java 1.0) | Современный (Java 1.2) |
| Итерация |
| Наследование | Наследует
💡Совет: В современной разработке на Java
📲 Мы в MAX
👉@BookJava
HashMap и Hashtable в Java? Если вы работаете с Java, то наверняка сталкивались с
HashMap и Hashtable. Оба используются для хранения пар "ключ-значение", но между ними есть важные различия. Давайте разберемся! 1. Синхронизация (Потокобезопасность)
-
Hashtable: - Синхронизирован (потокобезопасен). Все его методы синхронизированы, то есть только один поток может работать с ним одновременно.
- Это делает
Hashtable безопасным для многопоточных сред, но может снижать производительность в однопоточных сценариях. -
HashMap: - Не синхронизирован (не потокобезопасен). Несколько потоков могут обращаться к нему одновременно, что может привести к проблемам в многопоточных средах.
- Для потокобезопасности можно использовать
Collections.synchronizedMap(new HashMap<>()) или ConcurrentHashMap. 2. Null-ключи и Null-значения
-
Hashtable: - Не позволяет использовать
null в качестве ключа или значения. Попытка добавить null вызовет NullPointerException. -
HashMap: - Разрешает один
null - ключ и множество null -значений. 3. Производительность
-
Hashtable: - Медленнее из-за накладных расходов на синхронизацию.
-
HashMap: - Быстрее в однопоточных средах, так как не синхронизирован.
4. Наследие
-
Hashtable: - Считается устаревшим классом (появился в Java 1.0). Не является частью Java Collections Framework.
-
HashMap: - Часть Java Collections Framework (появился в Java 1.2). Более современный и широко используемый.
5. Итерация
-
Hashtable: - Использует
Enumeration для перебора ключей и значений. -
HashMap: - Использует
Iterator, который более гибкий и позволяет удалять элементы во время перебора. 6. Наследование
-
Hashtable: - Наследуется от класса
Dictionary (абстрактный класс, который сейчас считается устаревшим). -
HashMap: - Наследуется от
AbstractMap, который является частью Java Collections Framework. 7. Рекомендации по использованию
- Используйте
HashMap, если: - Работаете в однопоточной среде.
- Нужна высокая производительность.
- Требуется поддержка
null-ключей или значений. - Используйте
Hashtable, если: - Нужна потокобезопасность в многопоточной среде.
- Однако в современной Java
ConcurrentHashMap предпочтительнее, так как он обеспечивает лучшую производительность и масштабируемость. Пример кода
Hashtable:
Hashtable<String, Integer> hashtable = new Hashtable<>();
hashtable.put("one", 1);
hashtable.put("two", 2);
// hashtable.put(null, 3); // Выбросит NullPointerException
System.out.println(hashtable);
HashMap:
HashMap<String, Integer> hashMap = new HashMap<>();
hashMap.put("one", 1);
hashMap.put("two", 2);
hashMap.put(null, 3); // Разрешено
System.out.println(hashMap);
Итоговая таблица
| Особенность |
Hashtable | HashMap ||-------------------------|---------------------------------|-------------------------------|
| Синхронизация | Синхронизирован | Не синхронизирован |
| Null-ключи/значения | Запрещены | Разрешены |
| Производительность | Медленнее | Быстрее |
| Наследие | Устаревший (Java 1.0) | Современный (Java 1.2) |
| Итерация |
Enumeration | Iterator || Наследование | Наследует
Dictionary | Наследует AbstractMap |💡Совет: В современной разработке на Java
HashMap используется чаще. Если нужна потокобезопасность, лучше выбрать ConcurrentHashMap, а не Hashtable.👉@BookJava
Please open Telegram to view this post
VIEW IN TELEGRAM
❤4🔥2👍1👎1
🛒 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
🔥4
🎯 Открытый урок «Linq на практике».
🗓 14 января в 20:00 МСК
🆓 Бесплатно. Урок в рамках старта курса «C# Developer».
На вебинаре будут рассмотрены:
✔️ синтаксис операторов linq;
✔️ синтаксис компараторов, применяемых в linq-запросах;
✔️ примеры linq-запросов для наиболее популярных коллекций.
Кому будет полезно:
- данная тема будет интересна всем, кто работает с массивами данных в рамках .NET. Вы сможете эффективно использовать простой синтаксис для наиболее частых операций применяемых в рамках работы с коллекциями.
Что вы получите:
- вы сможете писать свои linq-запросы, опираясь на синтаксис linq.Будете знать разницу при применении тех или иных методов в рамках написания linq-запросов.
🔗 Ссылка на регистрацию: https://vk.cc/cTdPQ7
Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576
🗓 14 января в 20:00 МСК
🆓 Бесплатно. Урок в рамках старта курса «C# Developer».
На вебинаре будут рассмотрены:
Кому будет полезно:
- данная тема будет интересна всем, кто работает с массивами данных в рамках .NET. Вы сможете эффективно использовать простой синтаксис для наиболее частых операций применяемых в рамках работы с коллекциями.
Что вы получите:
- вы сможете писать свои linq-запросы, опираясь на синтаксис linq.Будете знать разницу при применении тех или иных методов в рамках написания linq-запросов.
🔗 Ссылка на регистрацию: https://vk.cc/cTdPQ7
Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1