Перейти к содержимому

Collectors tolist что возвращает

  • автор:

Collectors tolist что возвращает

Большинство операций класса Stream, которые модифицируют набор данных, возвращают этот набор в виде потока. Однако бывают ситуации, когда хотелось бы получить данные не в виде потока, а в виде обычной коллекции, например, ArrayList или HashSet. И для этого у класса Stream определен метод collect . Первая версия метода принимает в качестве параметра функцию преобразования к коллекции:

 R collect(Collector collector)

Параметр R представляет тип результата метода, параметр Т — тип элемента в потоке, а параметр А — тип промежуточных накапливаемых данных. В итоге параметр collector представляет функцию преобразования потока в коллекцию.

Эта функция представляет объект Collector, который определен в пакете java.util.stream. Мы можем написать свою реализацию функции, однако Java уже предоставляет ряд встроенных функций, определенных в классе Collectors :

  • toList() : преобразование к типу List
  • toSet() : преобразование к типу Set
  • toMap() : преобразование к типу Map

Например, преобразуем набор в потоке в список:

import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.stream.Collectors; public class Program < public static void main(String[] args) < Listphones = new ArrayList(); Collections.addAll(phones, "iPhone 8", "HTC U12", "Huawei Nexus 6P", "Samsung Galaxy S9", "LG G6", "Xiaomi MI6", "ASUS Zenfone 2", "Sony Xperia Z5", "Meizu Pro 6", "Lenovo S850"); List filteredPhones = phones.stream() .filter(s->s.length() <10) .collect(Collectors.toList()); for(String s : filteredPhones)< System.out.println(s); >> >

Использование метода toSet() аналогично.

Set filteredPhones = phones.stream() .filter(s->s.length()<10) .collect(Collectors.toSet());

Для применения метода toMap() надо задать ключ и значение. Например, пусть у нас есть следующая модель:

class Phone < private String name; private int price; public Phone(String name, int price)< this.name=name; this.price=price; >public String getName() < return name; >public int getPrice() < return price; >>

Теперь применим метод toMap() :

import java.util.Map; import java.util.stream.Collectors; import java.util.stream.Stream; public class Program < public static void main(String[] args) < StreamphoneStream = Stream.of(new Phone("iPhone 8", 54000), new Phone("Nokia 9", 45000), new Phone("Samsung Galaxy S9", 40000), new Phone("LG G6", 32000)); Map phones = phoneStream .collect(Collectors.toMap(p->p.getName(), t->t.getPrice())); phones.forEach((k,v)->System.out.println(k + " " + v)); > > class Phone < private String name; private int price; public Phone(String name, int price)< this.name=name; this.price=price; >public String getName() < return name; >public int getPrice() < return price; >>

Лямбда-выражение p->p.getName() получает значение для ключа элемента, а t->t.getPrice() - извлекает значение элемента.

Если нам надо создать какой-то определенный тип коллекции, например, HashSet, то мы можем использовать специальные функции, которые определены в классах-коллекций. Например, получим объект HashSet:

import java.util.HashSet; import java.util.stream.Collectors; import java.util.stream.Stream; public class Program < public static void main(String[] args) < Streamphones = Stream.of("iPhone 8", "HTC U12", "Huawei Nexus 6P", "Samsung Galaxy S9", "LG G6", "Xiaomi MI6", "ASUS Zenfone 2", "Sony Xperia Z5", "Meizu Pro 6", "Lenovo S850"); HashSet filteredPhones = phones.filter(s->s.length()<12). collect(Collectors.toCollection(HashSet::new)); filteredPhones.forEach(s->System.out.println(s)); > >

Выражение HashSet::new представляет функцию создания коллекции. Аналогичным образом можно получать другие коллекции, например, ArrayList:

ArrayList result = phones.collect(Collectors.toCollection(ArrayList::new));

Вторая форма метода collect имеет три параметра:

 R collect(Supplier supplier, BiConsumer accumulator, BiConsumer combiner)
  • supplier : создает объект коллекции
  • accumulator : добавляет элемент в коллекцию
  • combiner : бинарная функция, которая объединяет два объекта

Применим эту версию метода collect:

import java.util.ArrayList; import java.util.stream.Collectors; import java.util.stream.Stream; public class Program < public static void main(String[] args) < Streamphones = Stream.of("iPhone 8", "HTC U12", "Huawei Nexus 6P", "Samsung Galaxy S9", "LG G6", "Xiaomi MI6", "ASUS Zenfone 2", "Sony Xperia Z5", "Meizu Pro 6", "Lenovo S850"); ArrayList filteredPhones = phones.filter(s->s.length()<12) .collect( ()->new ArrayList(), // создаем ArrayList (list, item)->list.add(item), // добавляем в список элемент (list1, list2)-> list1.addAll(list2)); // добавляем в список другой список filteredPhones.forEach(s->System.out.println(s)); > >

Collectors Класс

Некоторые сведения относятся к предварительной версии продукта, в которую до выпуска могут быть внесены существенные изменения. Майкрософт не предоставляет никаких гарантий, явных или подразумеваемых, относительно приведенных здесь сведений.

Collector Реализации, реализующие различные полезные операции сокращения, такие как накопление элементов в коллекции, суммирование элементов в соответствии с различными критериями и т. д.

[Android.Runtime.Register("java/util/stream/Collectors", ApiSince=24, DoNotGenerateAcw=true)] public sealed class Collectors : Java.Lang.Object
[] type Collectors = class inherit Object

Наследование
Collectors

Комментарии

Collector Реализации, реализующие различные полезные операции сокращения, такие как накопление элементов в коллекции, суммирование элементов в соответствии с различными критериями и т. д.

Ниже приведены примеры использования предопределенных сборщиков для выполнения общих изменяемых задач сокращения.

 list = people.stream() .map(Person::getName) .collect(Collectors.toList()); // Accumulate names into a TreeSet Set set = people.stream() .map(Person::getName) .collect(Collectors.toCollection(TreeSet::new)); // Convert elements to strings and concatenate them, separated by commas String joined = things.stream() .map(Object::toString) .collect(Collectors.joining(", ")); // Compute sum of salaries of employee int total = employees.stream() .collect(Collectors.summingInt(Employee::getSalary)); // Group employees by department Map> byDept = employees.stream() .collect(Collectors.groupingBy(Employee::getDepartment)); // Compute sum of salaries by department Map totalByDept = employees.stream() .collect(Collectors.groupingBy(Employee::getDepartment, Collectors.summingInt(Employee::getSalary))); // Partition students into passing and failing Map> passingFailing = students.stream() .collect(Collectors.partitioningBy(s -> s.getGrade() >= PASS_THRESHOLD)); > 

Добавлено в версии 1.8.

Части этой страницы являются изменениями, основанными на работе, созданной и совместно используемой проектом Android и используемой в соответствии с условиями, Creative Commons 2.5 Attribution License.

Свойства

Возвращает класс среды выполнения данного объекта Object .

Дескриптор базового экземпляра Android.

Collector Реализации, реализующие различные полезные операции сокращения, такие как накопление элементов в коллекции, суммирование элементов в соответствии с различными критериями и т. д.

Collector Реализации, реализующие различные полезные операции сокращения, такие как накопление элементов в коллекции, суммирование элементов в соответствии с различными критериями и т. д.

Collector Реализации, реализующие различные полезные операции сокращения, такие как накопление элементов в коллекции, суммирование элементов в соответствии с различными критериями и т. д.

Этот API поддерживает инфраструктуру Mono для Android и не предназначен для использования непосредственно из кода.

Этот API поддерживает инфраструктуру Mono для Android и не предназначен для использования непосредственно из кода.

Методы

Возвращает значение Collector , которое создает среднее арифметическое функции с двойным значением, применяемой к входным элементам.

Возвращает значение , Collector которое создает среднее арифметическое для целочисленной функции, применяемой к входным элементам.

Возвращает значение , Collector которое создает среднее арифметическое функции с длинным значением, применяемой к входным элементам.

Создает и возвращает копию этого объекта.

Адаптирует для Collector выполнения дополнительного завершающего преобразования.

Collector Возвращает прием элементов типа T , который подсчитывает количество входных элементов.

Collector Реализации, реализующие различные полезные операции сокращения, такие как накопление элементов в коллекции, суммирование элементов в соответствии с различными критериями и т. д.

Collector Реализации, реализующие различные полезные операции сокращения, такие как накопление элементов в коллекции, суммирование элементов в соответствии с различными критериями и т. д.

Указывает, равен ли какой-то другой объект этому объекту.

Адаптирует Collector к одному, принимающему элементы одного типа T , применяя предикат к каждому входному элементу и накапливая только в том случае, если предикат возвращает true .

Возвращает значение хэш-кода для объекта.

Возвращает объект , Collector реализующий операцию "группировать по" для входных элементов типа T , группирование элементов в соответствии с функцией классификации и возврат результатов в Map .

Возвращает объект , Collector реализующий каскадную операцию "группировать по" для входных элементов типа T , группируя элементы в соответствии с функцией классификации, а затем выполняя операцию уменьшения значений, связанных с заданным ключом, с помощью указанного нижестоящего Collector элемента .

Возвращает объект , Collector реализующий каскадную операцию "группировать по" для входных элементов типа T , группируя элементы в соответствии с функцией классификации, а затем выполняя операцию уменьшения значений, связанных с заданным ключом, с помощью указанного нижестоящего Collector элемента .

Возвращает параллельную Collector операцию "группировать по" для входных элементов типа T , группируя элементы в соответствии с функцией классификации.

Возвращает параллельную Collector реализацию каскадной операции "группировать по" для входных элементов типа T , группирования элементов в соответствии с функцией классификации, а затем выполнения операции уменьшения значений, связанных с заданным ключом, с помощью указанного нижестоящего Collector элемента .

Возвращает параллельную Collector реализацию каскадной операции "группировать по" для входных элементов типа T , группирования элементов в соответствии с функцией классификации, а затем выполнения операции уменьшения значений, связанных с заданным ключом, с помощью указанного нижестоящего Collector элемента .

Вызывается сборщиком мусора для объекта , когда сборка мусора определяет, что больше нет ссылок на объект .

Возвращает объект Collector , сцепляющий входные элементы в String , в порядке встреч.

Возвращает объект , Collector сцепляющий входные элементы, разделенные указанным разделителем, в порядке встречи.

Возвращает объект , Collector сцепляющий входные элементы, разделенные указанным разделителем, с указанным префиксом и суффиксом в порядке встреч.

Возвращает объект , Collector сцепляющий входные элементы, разделенные указанным разделителем, в порядке встречи.

Возвращает объект , Collector сцепляющий входные элементы, разделенные указанным разделителем, с указанным префиксом и суффиксом в порядке встреч.

Адаптирует Collector принимаюющие элементы типа U к одному принимающему элементу типа T путем применения функции сопоставления к каждому входным элементу перед накоплением.

Возвращает объект Collector , который создает максимальный элемент в соответствии с заданным Comparator , описанным Optional как .

Возвращает объект , Collector который создает минимальный элемент в соответствии с заданным Comparator , описанным Optional как .

Пробуждает один поток, ожидающий монитора этого объекта.

Пробуждает все потоки, ожидающие на мониторе этого объекта.

Возвращает , Collector который секционирует входные элементы в соответствии с Predicate и упорядочивает их в Map> .

Collector Возвращает , который секционирует входные элементы в соответствии с Predicate , уменьшает значения в каждой секции в соответствии с другой Collector и упорядочивает их в Map , значения которого являются результатом нисходящего сокращения.

Возвращает объект , Collector выполняющий уменьшение входных элементов в заданном BinaryOperator объекте .

Возвращает объект , Collector выполняющий уменьшение входных элементов в заданном BinaryOperator объекте с помощью предоставленного удостоверения.

Возвращает объект , Collector выполняющий уменьшение входных элементов в рамках указанной функции сопоставления и BinaryOperator .

Возвращает объект , Collector который применяет double функцию сопоставления для создания каждого входного элемента, и возвращает сводную статистику для результирующего значения.

Возвращает объект , Collector который применяет int функцию сопоставления для создания каждого входного элемента, и возвращает сводную статистику для результирующего значения.

Возвращает объект , Collector который применяет long функцию сопоставления для создания каждого входного элемента, и возвращает сводную статистику для результирующего значения.

Возвращает объект Collector , который создает сумму функции с двойным значением, применяемой к входным элементам.

Возвращает объект , Collector который создает сумму целочисленной функции, применяемой к входным элементам.

Возвращает объект , Collector который создает сумму функции с длинным значением, применяемой к входным элементам.

Collector Реализации, реализующие различные полезные операции сокращения, такие как накопление элементов в коллекции, суммирование элементов в соответствии с различными критериями и т. д.

Возвращает объект Collector , который накапливает входные элементы в новый Collection объект в порядке встречи.

Возвращает параллельный Collector объект , который накапливает элементы в , ConcurrentMap ключи и значения которого являются результатом применения предоставленных функций сопоставления к входным элементам.

Возвращает параллельный Collector объект , который накапливает элементы в , ConcurrentMap ключи и значения которого являются результатом применения предоставленных функций сопоставления к входным элементам.

Возвращает параллельный Collector объект , который накапливает элементы в , ConcurrentMap ключи и значения которого являются результатом применения предоставленных функций сопоставления к входным элементам.

Возвращает объект , Collector который накапливает входные элементы в новый List объект .

Возвращает объект , Collector который накапливает элементы в , Map ключи и значения которых являются результатом применения предоставленных функций сопоставления к входным элементам.

Возвращает объект , Collector который накапливает элементы в , Map ключи и значения которых являются результатом применения предоставленных функций сопоставления к входным элементам.

Возвращает объект , Collector который накапливает элементы в , Map ключи и значения которых являются результатом применения предоставленных функций сопоставления к входным элементам.

Возвращает объект , Collector который накапливает входные элементы в новый Set объект .

Возвращает строковое представление объекта.

Возвращает объект , Collector который накапливает входные элементы в неизменяемый список в порядке встречи.

Возвращает объект , Collector который накапливает входные элементы в неизменяемую карту, ключи и значения которой являются результатом применения предоставленных функций сопоставления к входным элементам.

Возвращает объект , Collector который накапливает входные элементы в неизменяемую карту, ключи и значения которой являются результатом применения предоставленных функций сопоставления к входным элементам.

Возвращает объект Collector , который накапливает входные элементы в неизменяемый набор.

Collector Реализации, реализующие различные полезные операции сокращения, такие как накопление элементов в коллекции, суммирование элементов в соответствии с различными критериями и т. д.

Вызывает ожидание текущего потока, пока он не пробудится, как правило, из-за или>прерывания или прерывания.>

Вызывает ожидание текущего потока, пока он не пробудится, как правило, путем или>прерывания или прерывания<> или до истечения определенного количества реального времени.

Вызывает ожидание текущего потока, пока он не пробудится, как правило, путем или>прерывания или прерывания<> или до истечения определенного количества реального времени.

Явные реализации интерфейса

Collector Реализации, реализующие различные полезные операции сокращения, такие как накопление элементов в коллекции, суммирование элементов в соответствии с различными критериями и т. д.

Collector Реализации, реализующие различные полезные операции сокращения, такие как накопление элементов в коллекции, суммирование элементов в соответствии с различными критериями и т. д.

Collector Реализации, реализующие различные полезные операции сокращения, такие как накопление элементов в коллекции, суммирование элементов в соответствии с различными критериями и т. д.

Collector Реализации, реализующие различные полезные операции сокращения, такие как накопление элементов в коллекции, суммирование элементов в соответствии с различными критериями и т. д.

Collector Реализации, реализующие различные полезные операции сокращения, такие как накопление элементов в коллекции, суммирование элементов в соответствии с различными критериями и т. д.

Collector Реализации, реализующие различные полезные операции сокращения, такие как накопление элементов в коллекции, суммирование элементов в соответствии с различными критериями и т. д.

Collector Реализации, реализующие различные полезные операции сокращения, такие как накопление элементов в коллекции, суммирование элементов в соответствии с различными критериями и т. д.

Методы расширения

Выполняет преобразование типа, проверенного средой выполнения Android.

Collector Реализации, реализующие различные полезные операции сокращения, такие как накопление элементов в коллекции, суммирование элементов в соответствии с различными критериями и т. д.

Collector Реализации, реализующие различные полезные операции сокращения, такие как накопление элементов в коллекции, суммирование элементов в соответствии с различными критериями и т. д.

Применение интерфейса Collector для работы с потоками в реальных Java-проектах

Автор статьи, перевод которой мы публикуем сегодня, хочет рассказать о том, как интерфейс Collector и сопутствующие механизмы используются в реальных проектах.

В Java-программировании при работе с потоками широкое применение находят методы класса Collectors . Эти методы позволяют возвращать либо объекты, в основе которых лежит базовый класс Collection , либо — скалярные значения. В первом случае, то есть — для возврата коллекций, применяют один из методов, имя которого выглядит как toXXX() , а во втором случае используется, например, метод reducing() .

Представим себе интернет-магазин, в котором есть корзина. Модель корзины выглядит так, как показано ниже.

Модель корзины

Если перевести эту диаграмму классов в код, опустив некоторые детали, то получится следующее.

Вот код класса Product , представляющего товар:

public class Product < private final Long id; // 1 private final String label; // 1 private final BigDecimal price; // 1 public Product(Long id, String label, BigDecimal price) < this.id = id; this.label = label; this.price = price; >@Override public boolean equals(Object object) < … >// 2 @Override public int hashCode() < … >// 2 > 

Здесь и далее в коде будут использоваться комментарии в виде чисел, подробности о которых будут приводиться после блока кода.

  1. Геттеры.
  2. Методы, которые зависят лишь от id .
public class Cart < private final Mapproducts = new HashMap<>(); // 1 public void add(Product product) < add(product, 1); >public void add(Product product, int quantity) < products.merge(product, quantity, Integer::sum); >public void remove(Product product) < products.remove(product); >public void setQuantity(Product product, int quantity) < products.put(product, quantity); >public Map getProducts() < return Collections.unmodifiableMap(products); // 2 >> 
  1. Товары организованы в виде словаря. Его ключами являются объекты класса Product , а значениями — количества товаров.
  2. Не забудем о том, что для обеспечения инкапсуляции данных нужно вернуть копию коллекции, предназначенную только для чтения.
  • Нужно вывести список строк, в каждой из которых содержится наименование товара и его цена, представляющая собой произведение количества заказанного товара на цену одной единицы товара.
  • Нужно вывести общую стоимость заказа.
public record CartRow(Product product, int quantity) < // 1 public CartRow(Map.Entryentry) < this(entry.getKey(), entry.getValue()); >public BigDecimal getRowPrice() < return product.getPrice().multiply(new BigDecimal(quantity)); >> 
  1. CartRow — это объект-значение. Смоделировать его можно, взяв за основу запись ( record ) Java 16.
var rows = cart.getProducts() .entrySet() .stream() .map(CartRow::new) .collect(Collectors.toList()); // 1 var price = cart.getProducts() .entrySet() .stream() .map(CartRow::new) .map(CartTow::getRowPrice) // 2 .reduce(BigDecimal.ZERO, BigDecimal:add) // 3 
  1. Собрать список строк.
  2. Вычислить цену для каждой строки.
  3. Вычислить общую стоимость заказа.

В результате — для того чтобы узнать и цену товаров в отдельных строках, и общую стоимость заказа, нам нужно создавать на основе объекта корзины два потока. Из одного мы получаем сведения о строках, из второго — сведения о ценах.

Это — не особенно удачный способ решения нашей задачи.

Мы хотели бы получить из одного потока и сведения о строках с данными о товарах и их ценах, и сведения, необходимые для подсчёта полной стоимости товаров, находящихся в корзине. Для этого нам нужна собственная реализация интерфейса Collector , которая, за один проход, возвращает нам и то и другое в виде одного объекта.

public class PriceAndRows < private BigDecimal price; // 1 private final Listrows = new ArrayList<>(); // 2 PriceAndRows(BigDecimal price, List rows) < this.price = price; this.rows.addAll(rows); >PriceAndRows() < this(BigDecimal.ZERO, new ArrayList<>()); > > 
  1. Итоговая стоимость заказа.
  2. Список строк, в которых могут выводиться названия товаров, цена за единицу товара и общая стоимость товаров одного вида.

Интерфейс Collector

supplier()
accumulator()
combiner()
finisher()
characteristics()

Теперь мы можем реализовать интерфейс Collector :

private class PriceAndRowsCollector implements Collector, PriceAndRows, PriceAndRows> < @Override public Suppliersupplier() < return PriceAndRows::new; // 1 >@Override public BiConsumer> accumulator() < return (priceAndRows, entry) ->< // 2 var row = new CartRow(entry); priceAndRows.price = priceAndRows.price.add(row.getRowPrice()); priceAndRows.rows.add(row); >; > @Override public BinaryOperator combiner() < return (c1, c2) ->< // 3 c1.price = c1.price.add(c2.price); var rows = new ArrayList<>(c1.rows); rows.addAll(c2.rows); return new PriceAndRows(c1.price, rows); >; > @Override public Function finisher() < return Function.identity(); // 4 >@Override public Set characteristics() < return Set.of(Characteristics.IDENTITY_FINISH); // 4 >> 
  1. Мутабельный контейнер является экземпляром PriceAndRows .
  2. Поместить в контейнер типа PriceAndRows элемент словаря, содержащий сведения о товаре и о его количестве.
  3. Два объекта типа PriceAndRows можно скомбинировать, суммировав общую стоимость товаров, хранящихся в них, и агрегировав соответствующие строки.
  4. Мутабельный контейнер может быть возвращён в неизменном виде.
var priceAndRows = cart.getProducts() .entrySet() .stream() .collect(new PriceAndRowsCollector()); 

Итоги

Большинство задач, касающихся работы с потоками и коллекциями, можно решить, используя стандартные методы класса Collectors . Но иногда возникает необходимость в создании собственной реализации интерфейса Collector , например — тогда, когда нужно наладить работу не с одной, а с несколькими коллекциями, или когда в итоге нужно получить не одно, а несколько скалярных значений.

Хотя, если раньше вы подобным не занимались, это и может показаться сложным, на самом деле, всё не так уж и сложно. Нужно лишь немного практики. Надеюсь, этот материал поможет вам научиться работать с классом Collectors и с интерфейсом Collector .

Код, проекта, который мы рассматривали, в формате Maven, можно найти в этом репозитории.

Пользуетесь ли вы классом Collectors и интерфейсом Collector в своих проектах?

What kind of List does Collectors.toList() return?

I am reading State of the Lambda: Libraries Edition, and am being surprised by one statement: Under the section Streams, there is the following:

List blue = shapes.stream() .filter(s -> s.getColor() == BLUE) .collect(Collectors.toList()); 
  • It assigns the variable to a List , which is completely fine.
  • stream() nor filter() decide what kind of list to use.
  • Collectors.toList() neither specifies the concrete type of List .

So, what concrete type (subclass) of List is being used here? Are there any guarantees?

asked Feb 20, 2014 at 15:32
67.9k 31 31 gold badges 131 131 silver badges 218 218 bronze badges

Since the toUnmodifiableList() method was added in Java 10, it would seem that the mutability of toList() could now be guaranteed.

Mar 28, 2020 at 15:04

3 Answers 3

So, what concrete type (subclass) of List is being used here? Are there any guarantees?

If you look at the documentation of Collectors#toList() , it states that - "There are no guarantees on the type, mutability, serializability, or thread-safety of the List returned". If you want a particular implementation to be returned, you can use Collectors#toCollection(Supplier) instead.

Supplier> supplier = () -> new LinkedList(); List blue = shapes.stream() .filter(s -> s.getColor() == BLUE) .collect(Collectors.toCollection(supplier)); 

And from the lambda, you can return whatever implementation you want of List .

Update:

Or, you can even use method reference:

List blue = shapes.stream() .filter(s -> s.getColor() == BLUE) .collect(Collectors.toCollection(LinkedList::new)); 

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *