Java stream api терминальные операторы

Терминальные операции Stream API

Ранее мы уже рассмотрели Промежуточные операции Stream API, а сейчас рассмотрим терминальные (конечные).

Промежуточные операции следует воспринимать как «отложенные», т.е. они не меняют сами данные, а только задают правила их изменения. А терминальные как раз инициируют всю цепочку преобразований, закрывают поток и возвращают модифицированные данные. Закрытый поток повторно использовать нельзя.

Преобразование в коллекцию

Самая распространённая терминальная операция collect(). Результатом может быть, например, список.

List fruits = Stream.of( «apple» , «banana» , «lemon» , «orange» )
// здесь могут быть ещё какие-то преобразования
.collect(Collectors.toList());

А можно преобразовать стрим из строк в мапу, причём ключом сделать первую букву соответствующего слова:

Map fruits = Stream.of( «apple» , «banana» , «lemon» , «orange» )
.collect(Collectors.toMap(e -> e.substring( 0 , 1 ), e -> e));
//

Итерация по элементам

Простой обход элементов стрима можно выполнить с помощью метода forEach(). Его смысл полностью аналогичен языковой конструкции for.

Здесь мы просто выводим в консоль значение каждого элемента стрима.

Подсчёт количества элементов

Аналог метода size() в коллекциях и поля length в массивах. В стримах для этого используется метод count(). Обратите внимание, что метод возвращает не int, а long.

Минимальное и максимальное значения

Как нетрудно догадаться, min() возвращает минимальное значение, а max() – максимальное. В качестве параметра они принимают класс Comparator.

Также обратите внимание, как мы обошли «одноразовость» потока. Чтобы не писать два раза конструкцию Stream.of(. ), мы использовали утилитарный класс Supplier<>. Вызов метода get() у него в действительности каждый раз создаёт новый поток с одними и теми же значениями.

Supplier streamSupplier = () -> Stream.of( 5 , 3 , 2 , 10 , 8 );
Optional min = streamSupplier.get().min(Comparator.naturalOrder()); // Optional[2]
Optional max = streamSupplier.get().max(Comparator.naturalOrder()); // Optional[10]

Читайте также:  Работа html верстальщиком удаленно

Поиск первого подходящего элемента

Метод findFirst() возвращает первый элемент стрима. Этот метод очень удобно использовать в паре с filter().

Optional first = Stream.of( 1 , 2 , 3 , 4 , 5 )
.filter(e -> e % 2 == 0 )
.findFirst(); // Optional[2]

В данном случае мы вернём первое чётное число, т.е. 2.

Соответствие всех элементов

Чтобы проверить все элементы стрима на соответствие некоторому условию, используйте метод allMatch(). Его результатом может быть только true или false.

В этом примере мы проверяем, что все элементы положительные.

Полное несоответствие

Если нужно проверить, что ни один элемент не удовлетворяет условию, воспользуйтесь методом noneMatch(). Перепишем предыдущий пример так:

Соответствие хотя бы одного элемента

Чтобы проверить наличие хотя бы одного элемента, удовлетворяющего условию, используйте метод anyMatch().

Источник

Stream API

Java-университет

Stream API — это новый способ работать со структурами данных в функциональном стиле. Stream (поток) API (описание способов, которыми одна компьютерная программа может взаимодействовать с другой программой) — это по своей сути поток данных. Сам термин «поток» довольно размыт в программировании в целом и в Java в частности.

Stream API - 1

С появлением Java 8 Stream API позволило программистам писать существенно короче то, что раньше занимало много строк кода, а именно — упростить работу с наборами данных, в частности, упростить операции фильтрации, сортировки и другие манипуляции с данными. Если у вас промежуточных операций нет, часто можно и нужно обойтись без стрима, иначе код будет сложнее чем без потока.

Stream API - 2

C чего, собственно, начать? С создания экземпляра Stream, который опирается на нужную нам коллекцию, массив или метод их и откуда соответственно будут браться данные:

 List list = new ArrayList(); list.add("One"); list.add("Two"); list.add("Three"); list.add("Four"); list.add("Five"); list.add("Six"); list.add("Seven"); list.add("Eight"); list.add("Nine"); list.add("Ten"); Stream stream = list.stream(); 
 IntStream.of(50, 60, 70, 80, 90, 100, 110, 120).filter(x -> x < 90).map(x ->x + 10) .limit(3).forEach(System.out::print); 
 int[] arr = = 90) continue; x += 10; count++; if (count > 3) break; System.out.print(x); > 

Stream API - 3

  • Пустой стрим: Stream.empty()
  • Стрим из List: list.stream()
  • Стрим из Map: map.entrySet().stream()
  • Стрим из массива: Arrays.stream(array)
  • Стрим из указанных элементов: Stream.of(«1», «2», «3»)
  • Промежуточные (“intermediate”, ещё называют “lazy”) — обрабатывают поступающие элементы и возвращают стрим. Промежуточных операторов в цепочке обработки элементов может быть много.
  • Терминальные (“terminal”, ещё называют “eager”) — обрабатывают элементы и завершают работу стрима, так что терминальный оператор в цепочке может быть только один.
 1.List list = new ArrayList(); 2.list.add("One"); … 11.list.add("Ten"); 12.Stream stream = list.stream(); 13.stream.filter(x-> x.toString().length() == 3).forEach(System.out::println); 
  • 1 — создаём список list ;
  • 2-11 — заполняем его тестовыми данными;
  • 12 — создаём обьект Stream ;
  • 13 — метод filter (фильтр) — промежуточный оператор, x приравнивается к одному элементу коллекции для перебора (как при for each ) и после -> мы указываем как фильтруется наша коллекция и так как это промежуточный оператор, отфильтрованная коллекция идёт дальше в метод forEach который в свою очередь является терминальным (конечным) аналогом перебора for each (Выражение System.out::println сокращенно от: x-> System.out.println(x)) , которое в свою очередь проходит по всем элементам переданной ему коллекции и выводит её)
Читайте также:  Java programming jar file

Stream API - 5

  • Обработка не начнётся до тех пор, пока не будет вызван терминальный оператор. list.stream().filter(s -> s > 5) (не возьмёт ни единого элемента из списка);
  • Экземпляр, стрима нельзя использовать более одного раза =( ;

Stream API - 6

 list.stream().filter(x-> x.toString().length() == 3).forEach(System.out::println); list.stream().forEach(x -> System.out.println(x)); 
 stream.filter(x-> x.toString().length() == 3).map(x -> x + " - the length of the letters is three").forEach(x -> System.out.println(x)); 

Stream API - 7

  • filter(Predicate predicate) фильтрует стрим, пропуская только те элементы, что проходят по условию (Predicate встроенный функциональный интерфейс, добавленный в Java SE 8 в пакет java.util.function . Проверяет значение на “true” и “false”);
  • map(Function mapper) даёт возможность создать функию с помощью которой мы будем изменять каждый элемент и пропускать его дальше (Функциональный интерфейс Function представляет функцию перехода от объекта типа T к объекту типа R)
  • flatMap(Function> mapper) — как и в случае с map , служат для преобразования в примитивный стрим.
 String[] array = ; Stream streamOfArray = Arrays.stream(array); streamOfArray.map(s->s.split("")) //Преобразование слова в массив букв .flatMap(Arrays::stream).distinct() //выравнивает каждый сгенерированный поток в один поток .collect(Collectors.toList()).forEach(System.out::println); 

В то время когда map преобразует в список потоков (точнее потоков) [stream1,stream2,stream3,stream4] =>Stream.of(stream1,stream2,stream3,stream4) :

 String[] array = ; Stream streamOfArray = Arrays.stream(array); streamOfArray.map(s->s.split("")) //Преобразование слова в массив букв .map(Arrays::stream).distinct() //Сделать массив в отдельный поток .collect(Collectors.toList()).forEach(System.out::println); 
  • flatMapToDouble(Function mapper)
  • flatMapToInt(Function mapper)
  • flatMapToLong(Function mapper)
 Stream.of(2, 3, 0, 1, 3) .flatMapToInt(x -> IntStream.range(0, x)) .forEach(System.out::print);// 010120012 
 Stream.of(2, 3, 0, 1, 3) .map(x -> IntStream.range(0, x)) .forEach(System.out::print);//перечень стримов(потоков); 
 stream.limit(5).forEach(x -> System.out.println(x)); 
 stream.skip(3).forEach(x -> System.out.println(x)); 
 stream.sorted().forEach(x -> System.out.println(x)); 
 Predicate isPositive = x -> x > 0; System.out.println(isPositive.test(3)); // true System.out.println(isPositive.test(-9)); // false 

Stream API - 8

  • forEach(Consumer action) – аналог for each (Consumer выполняет некоторое действие над объектом типа T, при этом ничего не возвращая);
  • count() – возвращает количество елементов стрима: System.out.println(stream.count());
  • collect(Collector collector) – метод собирает все элементы в список, множество или другую коллекцию, сгруппировывает элементы по какому-нибудь критерию, объединяет всё в строку и т.д.:
 List list = Stream.of(“One”, “Two”, “Three”).collect(Collectors.toList()); 
 int sum = Stream.of(1, 2, 3, 4, 5).reduce(10, (acc, x) -> acc + x);// = 25 
 Stream.of(1, 2, 3, 4, 9).findFirst(); 
 Stream.of(1, 2, 3, 4, 9).allMatch(x -> x  
 Stream.of(1, 2, 3, 4, 9).anyMatch(x -> x >= 7);//true 
 Stream.of(1, 2, 3, 4, 9).noneMatch(x -> x >= 7);//false 
 List list = Stream.of(99, 2, 3).collect(Collectors.toList()); 
 Set set = Stream.of(99, 2, 3).collect(Collectors.toSet()); 
 Long count = Stream.of("1", "2", "3", "4").collect(Collectors.counting()); 
 String a = Stream.of("s", "u" ,"p", "e", "r").collect(Collectors.joining()); System.out.println(a); // super String b = Stream.of("s", "u", "p", "e", "r").collect(Collectors.joining("-")); System.out.println(b); // s-u-p-e-r String c = Stream.of("s", "u", "p", "e", "r").collect(Collectors.joining(" -> ", "[ ", " ]")); System.out.println(c); // [ s -> u -> p -> e -> r ] 

Источник

Оцените статью