Ответ
Группировка в Java Stream API — это операция терминального сбора (collect), которая распределяет элементы потока (Stream) по различным группам на основе заданной функции-классификатора. Результатом является Map<K, List<V>>, где ключ (K) — результат функции классификатора, а значение — список элементов, попавших в эту группу.
Базовый пример: Группировка строк по их длине.
import java.util.*;
import java.util.stream.*;
List<String> words = Arrays.asList("apple", "banana", "fig", "cherry", "date");
Map<Integer, List<String>> wordsByLength = words.stream()
.collect(Collectors.groupingBy(String::length));
// Результат в wordsByLength:
// {3=[fig], 4=[date], 5=[apple], 6=[banana, cherry]}
Расширенные возможности с Collectors.groupingBy:
-
Группировка с последующим сбором (downstream collector): Можно не просто собирать элементы в
List, а сразу выполнить над ними другую агрегацию.// Подсчет количества слов каждой длины Map<Integer, Long> countByLength = words.stream() .collect(Collectors.groupingBy(String::length, Collectors.counting())); // Результат: {3=1, 4=1, 5=1, 6=2} -
Изменение типа возвращаемой Map:
// Группировка в TreeMap (отсортированная по ключу) Map<Integer, List<String>> sortedMap = words.stream() .collect(Collectors.groupingBy(String::length, TreeMap::new, Collectors.toList())); -
Многоуровневая (каскадная) группировка:
// Сначала по длине, затем по первой букве Map<Integer, Map<Character, List<String>>> multiLevel = words.stream() .collect(Collectors.groupingBy(String::length, Collectors.groupingBy(s -> s.charAt(0))));
Ключевой метод: java.util.stream.Collectors.groupingBy().
Ответ 18+ 🔞
А, группировка в стримах, ну это ж классика, блядь! Сидишь такой, пишешь код, а тут надо разложить всё по полочкам, как в сортире — бумажки отдельно, журналы отдельно, а хуй с горы — в ведро. Так вот, groupingBy — это твоя волшебная палочка, которая из потока данных делает аккуратную мапу, где всё разложено по кучкам. Как дворник-перфекционист, только в коде.
Смотри, в чём суть, ёпта. Берёшь ты поток, допустим, слов. И говоришь: «Солнышко, разложи-ка мне их по длине, а?». И он, такой умный, делает Map<Integer, List<String>>. Ключ — длина, значение — список всех слов такой длины. Проще пареной репы, аж в рот меня чих-пых!
import java.util.*;
import java.util.stream.*;
List<String> words = Arrays.asList("apple", "banana", "fig", "cherry", "date");
Map<Integer, List<String>> wordsByLength = words.stream()
.collect(Collectors.groupingBy(String::length));
// Смотри, что в мапе вышло, блядь:
// {3=[fig], 4=[date], 5=[apple], 6=[banana, cherry]}
Ну и что, скажешь, это и обезьяна напишет? А вот хуй там! Сила-то groupingBy в том, что ты можешь не просто в лист складывать, а сразу в каждой кучке делать какую-нибудь дичь. Например, посчитать, сколько там слов в каждой кучке, чтобы не париться потом с размерами.
// Считаем, сколько слов каждой длины, одним махом, блядь!
Map<Integer, Long> countByLength = words.stream()
.collect(Collectors.groupingBy(String::length, Collectors.counting()));
// Получаем: {3=1, 4=1, 5=1, 6=2} — два слова по шесть букв, всё чётко.
А ещё, представляешь, можно заказать не абы какую мапу, а конкретную. Скажешь: «Хочу TreeMap, чтобы ключи были по порядку, а то в HashMap они как попало лежат, волнение ебать!». И пожалуйста:
// Группируем сразу в TreeMap, чтоб ключи отсортированы были. Красота!
Map<Integer, List<String>> sortedMap = words.stream()
.collect(Collectors.groupingBy(String::length, TreeMap::new, Collectors.toList()));
Но это ещё цветочки, блядь. А вот ягодки — это когда группировка на группировке сидит и группировкой погоняет. Каскадная, ёперный театр! Сначала по длине, а внутри каждой длины — ещё и по первой букве. Получается мапа в мапе, как матрёшка, только полезная.
// Сначала по длине, потом по первой букве. Овердохуища вложенности!
Map<Integer, Map<Character, List<String>>> multiLevel = words.stream()
.collect(Collectors.groupingBy(String::length,
Collectors.groupingBy(s -> s.charAt(0))));
Вот и весь сказ, блядь. Collectors.groupingBy() — твой главный инструмент для наведения порядка в этом хаосе данных. Главное — не перегруппировать всё в одну кучу, а то получится пиздец, а не код.