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 Реализации, реализующие различные полезные операции сокращения, такие как накопление элементов в коллекции, суммирование элементов в соответствии с различными критериями и т. д.
Java Stream API #неОпятьАСнова #javaJunior #java8
Эта статья, как и все последующие и предыдущие – моя попытка структурировать полученные знания в процессе изучения Java. Здесь тезисно собрана вся основная информация по теме и те формулировки, которые показались мне наиболее удачными и понятными. Это мой конспект, если хотите.
Статья будет полезна тем, кто изучает или повторяет основы Java Core.
И тем, кто готовится к техническому интервью.
На источники, откуда черпалась информация, предоставлены ссылки в конце статьи.
Оглавление
- Основные понятия
- Интерфейс Stream
- Стрим примитивных типов
- Получить Stream
- Операции над Stream
- Intermediate Промежуточные операции
- Terminal Конечные операции
- Операция сведения Stream.reduce()
- Класс Optional
- Класс Collectors
- Список ссылок
Основные понятия
С выходом Java 8 появилась поддержка функционального программирования.
Стало возможным конструировать сложные цепочки операций над потоком данных.
Функциона́льное программи́рование — парадигма программирования, в которой процесс вычисления трактуется как вычисление значений функций в математическом понимании последних (в отличие от функций как подпрограмм в процедурном программировании).
Пакет java.util.stream содержит классы для поддержки операций с потоками элементов в функциональном стиле. Ключевой абстракцией, введенной в этом пакете, является Поток.
Stream API – по сути это поток данных и последовательные операции над ними.
Интерфейсы Stream, IntStream, LongStream и DoubleStream – это потоки объектов и примитивных типов int , long и double .
Интерфейс Stream
public interface Stream extends BaseStream
Интерфейс Stream представляет собой последовательность элементов, поддерживающих последовательные и параллельные агрегатные операции.
К агрегатным операциям относят различные операции над выборкой, например, получение числа элементов, получение минимального, максимального и среднего значения в выборке, а также суммирование значений.
Stream не предоставляет средств для прямого доступа к элементам или манипулирования ими. Вместо этого он описывает источник данных и вычислительные операции, которые будут выполняться над этими данными.
Стрим примитивных типов
Чтобы обеспечить способ работы с тремя наиболее часто используемыми типами примитивов – int , long и double – библиотека java.util.stream включает три реализации стрима примитивов:
public interface IntStream extends BaseStream
public interface LongStream extends BaseStream
public interface DoubleStream extends BaseStream
Создание потока примитивных типов mapToInt(), mapToDouble(), mapToLong()
List numbers = new ArrayList<>(); numbers.stream().mapToInt(value -> value); numbers.stream().mapToDouble(value -> value); numbers.stream().mapToLong(value -> value);
Стримы примитивных типов данных имеют ряд уникальных методов, например диапазон и сумма всех элементов потока.
Методы диапазона доступны только для IntStream и LongStream.
Существует два метода получения стрима из диапазона чисел:
range(int startInclusive, int endExclusive)
rangeClosed(int startInclusive, int endInclusive)
В методе range() второй аргумент метода не входит в диапазон чисел, в то время как метод rangeClosed() включает его в диапазон.
Запустить Stream
Поток элементов может быть получен разными способами, например:
Stream из List
List list = new ArrayList<>(); list.stream(); list.parallelStream(); // параллельный поток
Stream из Map
Map map = new HashMap<>(); map.entrySet().stream(); map.values().stream();
Stream из массива, используя статический метод класса Arrays
String[] array = new String[10]; Arrays.stream(array);
Stream из элементов, используя статические методы Классов-потоков
Stream.of("a", "b", "c"); // поток из элементов Stream.of(array); // поток из элементов массива Stream.of(list); // поток из элементов списка List Stream.generate(Math::random); // генерация потока рандомных чисел Stream.concat(stream1, stream2); // объединяет два потока в один IntStream.range(1, 10); // поток диапазона чисел от 1 до 9 IntStream.rangeClosed(1, 10); // поток диапазона чисел от 1 до 10
Stream из строк буфера BufferedReader
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in)); bufferedReader.lines();
Stream из строк файла через статический метод класса Files
Path path = Path.of("/root/test.txt"); Files.lines(path);
Stream из случайных чисел Random
Random random = new Random(); random.ints(); random.longs(); random.doubles();
Операции над Stream
Операции над потоком элементов бывают:
- Intermediate – Промежуточные
Не меняют данные, а только задают логику их изменения.
С их помощью можно составить последовательную цепь операций над элементами. - Terminal – Конечные
Запускают всю цепь промежуточных операций, закрываютпоток и возвращают модифицированные данные.
Промежуточные операции НЕ выполняются без терминальных.
После обработки стрим нельзя повторно использовать.
Операции над потоком могут выполняться как последовательно, так и параллельно.
Чтобы превратить обычный стрим в параллельный, нужно вызвать промежуточный оператор parallel()
Stream stream = list.stream(); stream.parallel();
Промежуточные операции. Intermediate
Данные операции удобно воспринимать как отложенные – они выполнятся когда их запустит конечная терминальная операция над стримом.
Провести операцию над каждым элементом peek()
Аналог forEach() , только промежуточный (нетерминальный)
Если в метод peek() передать функцию System.out::println , тогда все объекты будут выводиться на экран в момент, когда они будут проходить через поток.
Stream.of("a", "b", "c").peek(System.out::println);
Преобразовать данные из одного типа в другой map()
Можно передать функцию, которая преобразовывает один тип данных в другой.
Stream.of(1, 2, 3).map((x) -> String.valueOf(x)); Stream.of(1, 2, 3).map(String::valueOf); // лямбда выражение Stream.of("1", "2", "3").map(Integer::parseInt);
Отфильтровать элементы filter()
Stream.of(1, 2, 3, 4, 5).filter(n -> n < 4); // [1, 2, 3]
Удалить дублирующиеся элементы distinct()
Stream.of(1, 2, 3, 2, 4, 2, 5).distinct(); // [1, 2, 3, 4, 5]
Сортировка и обратная сортировка элементов sorted()
Stream.of(4, 2, 3, 5, 1).sorted(); // [1, 2, 3, 4, 5] Stream.of(4, 2, 3, 5, 1).sorted(Comparator.reverseOrder())
Лимит количества элементов limit()
Stream.of(1, 2, 3, 4, 5, 6).limit(3); // [1, 2, 3]
Пропустить первые элементы skip()
Stream.of(1, 2, 3, 4, 5).skip(2); // [3, 4, 5]
Сопоставить поток с развернутым потоком flatMap()
Возвращает поток, состоящий из результатов замены каждого элемента этого потока содержимым сопоставленного потока, полученного путем применения предоставленной функции сопоставления к каждому элементу.
List petNames = person.stream() .flatMap(person -> person.getPetName().stream()) .collect(Collectors.toList()); System.out.println(petNames); // [pet1, pet2, pet3, pet4, pet5]
Таким образом можно развернуть двухмерный массив
Integer[][] array2d = new Integer[][] < , >; Arrays.stream(array2d).flatMap(Arrays::stream); // [1, 2, 3, 4, 5]
Конечные операции. Terminal
Запускают всю цепь промежуточных операций и возвращают конечный результат, закрывают поток.
Собрать элементы потока и преобразовать их к нужному типу collect()
В аргумент метода нужно передать объект Collector.
Преобразовать поток в List Collectors.toList()
List collect = Stream.of("a", "b", "c").collect(Collectors.toList());
Преобразовать поток в строку String Collectors.joining()
String collect = Stream.of("a", "b", "c").collect(Collectors.joining());
Итерация по каждому элементу forEach()
Stream.of("a", "b", "c").forEach(System.out::println);
Узнать количество элементов стрима count()
Stream.of("a", "b", "c").count();
Найти минимальное и максимальное значение min() и max()
Сравнение происходит с помощью объекта Comparator.
Возвращают объект класса Optional – объект-контейнер, который может хранить null .
Метод get() – возвращает значение, которое хранит объект Optional.
Optional max = Stream.of(4, 2, 3, 5, 1) .max(Comparator.naturalOrder()); Integer maximum = max.get(); Integer minimum = Stream.of(4, 2, 3, 5, 1) .min(Comparator.naturalOrder()) .get();
Comparator удобно задать с помощью лямбда-функции:
Stream.of("a", "bb", "ccc") .min((s1, s2) -> s1.length() - s2.length()) .get(); Stream.of("a", "bb", "ccc") .max(Comparator.comparingInt(String::length)) .get();
Найти первый подходящий элемент findFirst()
Возвращает первый подходящий элемент из стрима и завершается.
Возвращают объект класса Optional.
Stream.of(1, 2, 3, 4, 5) .filter(e -> e % 2 == 0) .findFirst() .get();
Найти любой подходящий элемент findAny()
Возвращает любой подходящий элемент из стрима и завершается.
Аналог метода findFirst() для потоков, которые обрабатываются параллельно.
Найденный элемент не обязательно будет первый по порядку в потоке.
Stream.of(1, 2, 3, 4, 5, 6, 7, 8, 9, 10) .filter(e -> e % 2 == 0) .parallel() .findAny() .get();
Все элементы соответствуют условию allMatch()
Stream.of(1, 2, 3, 4, 5).allMatch(e -> e > 0); // true
Все элементы НЕ соответствуют условию noneMatch()
Stream.of(1, 2, 3, 4, 5).noneMatch(e -> e > 0); // false
Хотя бы один элемент соответствует условию anyMatch()
Stream.of(1, 2, 3, 4, 5).anyMatch(e -> e > 4); // true
Сумма элементов стрима sum()
Это метод классов-стримов примитивных типов данных:
IntStream, LongStream и DoubleStream
List integers = new ArrayList<>(); integers.stream() .mapToInt(i -> i) .sum();
Операция сведения Stream.reduce()
Позволяет получить один результат из последовательности элементов, неоднократно применяя операцию комбинирования к элементам в последовательности.
Участники операции сведения:
- Identity - элемент, который является начальным значением операции сокращения и результатом по умолчанию, если поток пуст.
- Accumulator - функция, которая принимает два параметра: частичный результат операции сведения и следующий элемент потока
- Combiner - функция, используемая для объединениячастичногорезультата операции сокращения и типами реализации аккумулятора.
Если используем последовательные потоки, типы аргументов аккумулятора и типы его реализации не совпадают – нужно использовать Combiner.
Сумма элементов списка
List numbers = Arrays.asList(1, 2, 3, 4, 5, 6); int sum = numbers.stream() .reduce(0, Integer::sum); int sum2 = numbers.stream() .reduce(0, (subtotal, element) -> subtotal + element);
Сумма элементов в параллельном потоке
В таких случаях нужно использовать функцию для объединения результатов подпотоков в один – это роль Combiner Комбинатора.
В приведенном примере эту роль выполняет метод Integer::sum
int sum = numbers .parallelStream() .reduce(0, (a, b) -> a + b, Integer::sum); int sum2 = ages .parallelStream() .reduce(0, Integer::sum, Integer::sum);
Объединение списка строк в одну сроку
List letters = Arrays.asList("a", "b", "c", "d", "e"); String result = letters.stream() .reduce("", String::concat); String result2 = letters.stream() .reduce("", (partialString, element) -> partialString + element);
Класс Optional
Методы интерфейса Stream findAny() , findFirst() , max() , min() и reduce() возвращают объект класса Optional
public final class Optional extends Object
Это объект-контейнер, который может содержать или не содержать нулевое значение.
Ссылка на объект класса Optional может быть null
Если значение присутствует, метод isPresent() вернет true
Позволяет избавиться от проверки на null
Без этого класса приходилось писать проверку на NullPointerException.
Благодарю этому один объект Optional можно сравнить с другим объектом Optional через метод equals() , даже если они хранят в себе ссылки на null .
Получить элемент Optional get()
Метод класса Optoinal – возвращает значение, если оно присутствует, в противном случае бросит NoSuchElementException .
Stream.of("1", "22", "333") .max(Comparator.comparingInt(String::length)) .get();
Класс Collectors
Метод collect() интерфейса Stream собирает данные в необходимую структуру данных, например в коллекции — List , Set , Map
public interface Collector
В метод collect() в качестве параметра принимает объект типа Collector.
Статические методы класса Collectors возвращают такой объект класса Collector.
public final class Collectors extends Object
Класс Collectors содержит статические методы для сбора элементов в коллекцию, обобщения и группировки элементов в соответствии с различными критериями и т. п., которые возвращают готовые объекты коллекций.
Преобразование потока в List toList()
list.stream().collect(Collectors.toList());
Преобразование потока в Set toSet()
list.stream().collect(Collectors.toSet());
Преобразование потока в Map toMap()
map.entrySet().stream() .map(e -> String.valueOf(e).split(" java">list.stream().collect(Collectors.joining(", "));
Сумма элементов потока summingInt(), summingDouble(), summingLong()
Например, сумма заработной платы сотрудников
List employees = new ArrayList<>() employees.stream() .collect(Collectors.summingDouble(Employee::getSalary)));
Сгруппировать элементы по условию groupingBy()
Группировка людей по стране
List people = new ArrayList<>() people.stream() .collect(Collectors.groupingBy(Person::getCountry));
Список ссылок на источники информации
- Stream API
- Промежуточные операции Stream API
- Терминальные операции Stream API
- Java 8 Stream flatMap()
- Java 8 Stream - Java Stream
- Guide to Stream.reduce()
Collectors tolist что возвращает
Чтобы сгруппировать данные по какому-нибудь признаку, нам надо использовать в связке метод collect() объекта Stream и метод Collectors.groupingBy() . Допустим, у нас есть следующий класс:
class Phone < private String name; private String company; private int price; public Phone(String name, String comp, int price)< this.name=name; this.company=comp; this.price = price; >public String getName() < return name; >public int getPrice() < return price; >public String getCompany() < return company; >>
И, к примеру, у нас есть набор объектов Phone, которые мы хотим сгруппировать по компании:
import java.util.List; import java.util.Map; import java.util.stream.Stream; import java.util.stream.Collectors; public class Program < public static void main(String[] args) < StreamphoneStream = Stream.of(new Phone("iPhone X", "Apple", 600), new Phone("Pixel 2", "Google", 500), new Phone("iPhone 8", "Apple",450), new Phone("Galaxy S9", "Samsung", 440), new Phone("Galaxy S8", "Samsung", 340)); Map phonesByCompany = phoneStream.collect( Collectors.groupingBy(Phone::getCompany)); for(Map.Entry item : phonesByCompany.entrySet()) < System.out.println(item.getKey()); for(Phone phone : item.getValue())< System.out.println(phone.getName()); >System.out.println(); > > >
Google Pixel 2 Apple iPhone X iPhone 8 Samsung Galaxy S9 Galaxy S8
Итак, для создания групп в метод phoneStream.collect() передается вызов функции Collectors.groupingBy() , которая с помощью выражения Phone::getCompany группирует объекты по компании. В итоге будет создан объект Map, в котором ключами являются названия компаний, а значениями - список связанных с компаниями телефонов.
Метод Collectors.partitioningBy
Метод Collectors.partitioningBy() имеет похожее действие, только он делит элементы на группы по принципу, соответствует ли элемент определенному условию. Например:
Map> phonesByCompany = phoneStream.collect( Collectors.partitioningBy(p->p.getCompany()=="Apple")); for(Map.Entry> item : phonesByCompany.entrySet()) < System.out.println(item.getKey()); for(Phone phone : item.getValue())< System.out.println(phone.getName()); >System.out.println(); >
В данном случае с помощью условия p->p.getCompany()=="Apple" мы смотрим, принадлежит ли телефон компании Apple. Если телефон принадлежит этой компании, то он попадает в одну группу, если нет, то в другую.
Метод Coollectors.counting
Метод Collectors.counting применяется в Collectors.groupingBy() для вычисления количества элементов в каждой группе:
Map phonesByCompany = phoneStream.collect( Collectors.groupingBy(Phone::getCompany, Collectors.counting())); for(Map.Entry item : phonesByCompany.entrySet())
Google -1 Apple - 2 Samsung - 2
Метод Collectors.summing
Метод Collectors.summing применяется для подсчета суммы. В зависимости от типа данных, к которым применяется метод, он имеет следующие формы: summingInt() , summingLong() , summingDouble() . Применим этот метод для подсчета стоимости всех смартфонов по компаниям:
Map phonesByCompany = phoneStream.collect( Collectors.groupingBy(Phone::getCompany, Collectors.summingInt(Phone::getPrice))); for(Map.Entry item : phonesByCompany.entrySet())
С помощью выражения Collectors.summingInt(Phone::getPrice)) мы указываем, что для каждой компании будет вычислять совокупная цена всех ее смартфонов. И поскольку вычисляется результат - сумма для значений типа int, то в качестве типа возвращаемой коллекции используется тип Map
Google - 500 Apple - 1050 Samsung - 780
Методы maxBy и minBy
Методы maxBy и minBy применяются для подсчета минимального и максимального значения в каждой группе. В качестве параметра эти методы принимают функцию компаратора, которая нужна для сравнения значений. Например, найдем для каждой компании телефон с минимальной ценой:
Map> phonesByCompany = phoneStream.collect( Collectors.groupingBy(Phone::getCompany, Collectors.minBy(Comparator.comparing(Phone::getPrice)))); for(Map.Entry> item : phonesByCompany.entrySet())
Google - Pixel 2 Apple - iPhone 8 Samsung - Galaxy S8
В качестве возвращаемого значения операции группировки используется объект Map> . Опять же поскольку группируем по компаниям, то ключом будет выступать строка, а значением - объект Optional .
Метод summarizing
Методы summarizingInt() / summarizingLong() / summarizingDouble() позволяют объединить в набор значения соответствующих типов:
import java.util.IntSummaryStatistics; //. Map priceSummary = phoneStream.collect( Collectors.groupingBy(Phone::getCompany, Collectors.summarizingInt(Phone::getPrice))); for(Map.Entry item : priceSummary.entrySet())
Метод Collectors.summarizingInt(Phone::getPrice)) создает набор, в который помещаются цены для всех телефонов каждой из групп. Данный набор инкапсулируется в объекте IntSummaryStatistics . Соответственно если бы мы применяли методы summarizingLong() или summarizingDouble() , то соответственно бы получали объекты LongSummaryStatistics или DoubleSummaryStatistics.
У этих объектов есть ряд методов, который позволяют выполнить различные атомарные операции над набором:
- getAverage() : возвращает среднее значение
- getCount() : возвращает количество элементов в наборе
- getMax() : возвращает максимальное значение
- getMin() : возвращает минимальное значение
- getSum() : возвращает сумму элементов
- accept() : добавляет в набор новый элемент
В данном случае мы получаем среднюю цену смартфонов для каждой группы.
Google - 500.0 Apple - 525.0 Samsung - 390.0
Метод mapping
Метод mapping позволяет дополнительно обработать данные и задать функцию отображения объектов из потока на какой-нибудь другой тип данных. Например:
Map> phonesByCompany = phoneStream.collect( Collectors.groupingBy(Phone::getCompany, Collectors.mapping(Phone::getName, Collectors.toList()))); for(Map.Entry> item : phonesByCompany.entrySet()) < System.out.println(item.getKey()); for(String name : item.getValue())< System.out.println(name); >>
Выражение Collectors.mapping(Phone::getName, Collectors.toList()) указывает, что в группу будут выделятся названия смартфонов, причем группа будет представлять объект List.