Клас Утиліт Collectors для Stream API
Метод collect() у Stream API вже знайомий нам як потужний інструмент для збору елементів потоку у зручні структури даних. Однак сам по собі collect() вимагає реалізації Collector, що може ускладнювати процес.
У цьому допомагає клас Collectors, який надає набір готових реалізацій для найпоширеніших операцій. Це спрощує такі завдання, як збір даних у колекції, групування та підрахунок, роблячи ці операції значно простішими.
Основні методи класу Collectors
Клас Collectors пропонує безліч готових рішень, що усуває необхідність ручної реалізації Collector. Ось деякі з основних методів:
Stream API також пропонує вбудований метод toList(), який ви вже використовували раніше. Цей метод має лаконічний синтаксис, що робить його переважним вибором. Однак ви можете використовувати будь-яку реалізацію, яка найкраще відповідає вашим потребам.
Перетворення списку на Map
Припустимо, у вас є список продуктів з їхніми цінами, збереженими у вигляді рядків у форматі Name=Price. Наша мета — створити Map, де ключем буде назва продукту, а значенням — його ціна.
Main.java
1234567891011121314151617181920package com.example; import java.util.List; import java.util.Map; import java.util.stream.Collectors; public class Main { public static void main(String[] args) { List<String> productData = List.of("Laptop:1500", "Smartphone:900", "Monitor:1200"); // Convert the list of strings into a `Map` by splitting the string at "=" Map<String, Integer> productPriceMap = productData.stream() .collect(Collectors.toMap( item -> item.split(":")[0], // Key - product name item -> Integer.parseInt(item.split(":")[1]) // Value - price )); System.out.println("Product Map: " + productPriceMap); } }
Тут використовується toMap() для розділення кожного рядка (split("=")) і створення Map<String, Integer>, де ключем є назва продукту, а значенням — його ціна як ціле число. Наприклад, рядок Laptop=1500 перетворюється на запис Laptop -> 1500.
Групування продуктів за першою літерою
Виконаємо групування продуктів за їхньою першою літерою, щоб побачити, які елементи починаються з однієї й тієї ж літери.
Main.java
12345678910111213141516171819202122package com.example; import java.util.List; import java.util.Map; import java.util.stream.Collectors; public class Main { public static void main(String[] args) { List<String> products = List.of( "Laptop", "Lamp", "Laser Printer", "Desktop PC", "Drone", "Smartphone", "Smartwatch", "Monitor", "Mouse" ); // Grouping products by the first letter of their name Map<Character, List<String>> groupedProducts = products.stream() .collect(Collectors.groupingBy(product -> product.charAt(0))); System.out.println("Products grouped by first letter: " + groupedProducts); } }
Програма створює List з назв продуктів і групує їх за першою літерою за допомогою groupingBy(). Результат зберігається у Map, де ключем є charAt(0), а значенням — список відповідних продуктів. Наприкінці груповані продукти виводяться.
Розділення цін
Collectors.partitioningBy — це спеціальний колектор у Stream API, який розділяє елементи на дві групи за заданим предикатом.
Map<Boolean, List<Integer>> partitionedPrices = prices.stream()
.collect(Collectors.partitioningBy(price -> price > 1000));
Повертає Map<Boolean, List<T>>, де true позначає елементи, що відповідають умові, а false — ті, що не відповідають.
Це корисно для розділення даних, наприклад, для фільтрації парних і непарних чисел або товарів з високою та низькою ціною.
Приклад
Розділимо ціни товарів на дві категорії: дорогі (більше $1000) і дешеві ($1000 або менше).
Main.java
123456789101112131415161718package com.example; import java.util.List; import java.util.Map; import java.util.stream.Collectors; public class Main { public static void main(String[] args) { List<Integer> prices = List.of(1500, 900, 1200, 1100, 300); // Partition prices into expensive and cheap categories Map<Boolean, List<Integer>> partitionedPrices = prices.stream() .collect(Collectors.partitioningBy(price -> price > 1000)); System.out.println("Expensive products: " + partitionedPrices.get(true)); System.out.print("Cheap products: " + partitionedPrices.get(false)); } }
Метод partitioningBy() розділяє список цін на дві групи. Якщо ціна більша за 1000, вона потрапляє під ключем true; інакше — під ключем false.
Підрахунок продуктів
Підрахунок кількості продуктів, що починаються з однієї й тієї ж літери.
Main.java
12345678910111213141516171819202122package com.example; import java.util.List; import java.util.Map; import java.util.stream.Collectors; public class Main { public static void main(String[] args) { List<String> products = List.of( "Laptop", "Lamp", "Laser Printer", "Desktop PC", "Dishwasher", "Drone", "Smartphone", "Smartwatch", "Speaker", "Monitor", "Mouse", "Microphone" ); // Count how many products start with each letter Map<Character, Long> countByLetter = products.stream() .collect(Collectors.groupingBy(product -> product.charAt(0), Collectors.counting())); System.out.println("Product count by first letter: " + countByLetter); } }
Програма обробляє List із продуктами за допомогою stream(), потім застосовує groupingBy() з charAt(0) для групування слів за першою літерою. Колектор counting() підраховує, скільки продуктів потрапляє до кожної групи, а фінальна Map зберігає літеру як ключ і кількість як значення.
Об'єднання назв продуктів
Об'єднання назв продуктів в один рядок з розділенням комами.
Main.java
12345678910111213141516package com.example; import java.util.List; import java.util.stream.Collectors; public class Main { public static void main(String[] args) { List<String> products = List.of("Laptop", "Smartphone", "Monitor"); // Join product names into a single comma-separated string String productNames = products.stream() .collect(Collectors.joining(", ")); System.out.println("Product list: " + productNames); } }
Метод Collectors.joining(", ") об'єднує всі назви продуктів в один рядок, розділяючи їх комами. У підсумку отриманий рядок виводиться для відображення списку продуктів у зручному для читання форматі.
1. Що виконує наступний код?
2. Який метод Collectors слід використовувати для групування продуктів за першою літерою?
Дякуємо за ваш відгук!
Запитати АІ
Запитати АІ
Запитайте про що завгодно або спробуйте одне із запропонованих запитань, щоб почати наш чат
Can you show examples of how to use each Collectors method?
What are some common use cases for groupingBy and partitioningBy?
How do I choose between toList(), toSet(), and toMap()?
Awesome!
Completion rate improved to 2.33
Клас Утиліт Collectors для Stream API
Свайпніть щоб показати меню
Метод collect() у Stream API вже знайомий нам як потужний інструмент для збору елементів потоку у зручні структури даних. Однак сам по собі collect() вимагає реалізації Collector, що може ускладнювати процес.
У цьому допомагає клас Collectors, який надає набір готових реалізацій для найпоширеніших операцій. Це спрощує такі завдання, як збір даних у колекції, групування та підрахунок, роблячи ці операції значно простішими.
Основні методи класу Collectors
Клас Collectors пропонує безліч готових рішень, що усуває необхідність ручної реалізації Collector. Ось деякі з основних методів:
Stream API також пропонує вбудований метод toList(), який ви вже використовували раніше. Цей метод має лаконічний синтаксис, що робить його переважним вибором. Однак ви можете використовувати будь-яку реалізацію, яка найкраще відповідає вашим потребам.
Перетворення списку на Map
Припустимо, у вас є список продуктів з їхніми цінами, збереженими у вигляді рядків у форматі Name=Price. Наша мета — створити Map, де ключем буде назва продукту, а значенням — його ціна.
Main.java
1234567891011121314151617181920package com.example; import java.util.List; import java.util.Map; import java.util.stream.Collectors; public class Main { public static void main(String[] args) { List<String> productData = List.of("Laptop:1500", "Smartphone:900", "Monitor:1200"); // Convert the list of strings into a `Map` by splitting the string at "=" Map<String, Integer> productPriceMap = productData.stream() .collect(Collectors.toMap( item -> item.split(":")[0], // Key - product name item -> Integer.parseInt(item.split(":")[1]) // Value - price )); System.out.println("Product Map: " + productPriceMap); } }
Тут використовується toMap() для розділення кожного рядка (split("=")) і створення Map<String, Integer>, де ключем є назва продукту, а значенням — його ціна як ціле число. Наприклад, рядок Laptop=1500 перетворюється на запис Laptop -> 1500.
Групування продуктів за першою літерою
Виконаємо групування продуктів за їхньою першою літерою, щоб побачити, які елементи починаються з однієї й тієї ж літери.
Main.java
12345678910111213141516171819202122package com.example; import java.util.List; import java.util.Map; import java.util.stream.Collectors; public class Main { public static void main(String[] args) { List<String> products = List.of( "Laptop", "Lamp", "Laser Printer", "Desktop PC", "Drone", "Smartphone", "Smartwatch", "Monitor", "Mouse" ); // Grouping products by the first letter of their name Map<Character, List<String>> groupedProducts = products.stream() .collect(Collectors.groupingBy(product -> product.charAt(0))); System.out.println("Products grouped by first letter: " + groupedProducts); } }
Програма створює List з назв продуктів і групує їх за першою літерою за допомогою groupingBy(). Результат зберігається у Map, де ключем є charAt(0), а значенням — список відповідних продуктів. Наприкінці груповані продукти виводяться.
Розділення цін
Collectors.partitioningBy — це спеціальний колектор у Stream API, який розділяє елементи на дві групи за заданим предикатом.
Map<Boolean, List<Integer>> partitionedPrices = prices.stream()
.collect(Collectors.partitioningBy(price -> price > 1000));
Повертає Map<Boolean, List<T>>, де true позначає елементи, що відповідають умові, а false — ті, що не відповідають.
Це корисно для розділення даних, наприклад, для фільтрації парних і непарних чисел або товарів з високою та низькою ціною.
Приклад
Розділимо ціни товарів на дві категорії: дорогі (більше $1000) і дешеві ($1000 або менше).
Main.java
123456789101112131415161718package com.example; import java.util.List; import java.util.Map; import java.util.stream.Collectors; public class Main { public static void main(String[] args) { List<Integer> prices = List.of(1500, 900, 1200, 1100, 300); // Partition prices into expensive and cheap categories Map<Boolean, List<Integer>> partitionedPrices = prices.stream() .collect(Collectors.partitioningBy(price -> price > 1000)); System.out.println("Expensive products: " + partitionedPrices.get(true)); System.out.print("Cheap products: " + partitionedPrices.get(false)); } }
Метод partitioningBy() розділяє список цін на дві групи. Якщо ціна більша за 1000, вона потрапляє під ключем true; інакше — під ключем false.
Підрахунок продуктів
Підрахунок кількості продуктів, що починаються з однієї й тієї ж літери.
Main.java
12345678910111213141516171819202122package com.example; import java.util.List; import java.util.Map; import java.util.stream.Collectors; public class Main { public static void main(String[] args) { List<String> products = List.of( "Laptop", "Lamp", "Laser Printer", "Desktop PC", "Dishwasher", "Drone", "Smartphone", "Smartwatch", "Speaker", "Monitor", "Mouse", "Microphone" ); // Count how many products start with each letter Map<Character, Long> countByLetter = products.stream() .collect(Collectors.groupingBy(product -> product.charAt(0), Collectors.counting())); System.out.println("Product count by first letter: " + countByLetter); } }
Програма обробляє List із продуктами за допомогою stream(), потім застосовує groupingBy() з charAt(0) для групування слів за першою літерою. Колектор counting() підраховує, скільки продуктів потрапляє до кожної групи, а фінальна Map зберігає літеру як ключ і кількість як значення.
Об'єднання назв продуктів
Об'єднання назв продуктів в один рядок з розділенням комами.
Main.java
12345678910111213141516package com.example; import java.util.List; import java.util.stream.Collectors; public class Main { public static void main(String[] args) { List<String> products = List.of("Laptop", "Smartphone", "Monitor"); // Join product names into a single comma-separated string String productNames = products.stream() .collect(Collectors.joining(", ")); System.out.println("Product list: " + productNames); } }
Метод Collectors.joining(", ") об'єднує всі назви продуктів в один рядок, розділяючи їх комами. У підсумку отриманий рядок виводиться для відображення списку продуктів у зручному для читання форматі.
1. Що виконує наступний код?
2. Який метод Collectors слід використовувати для групування продуктів за першою літерою?
Дякуємо за ваш відгук!