Metanit java stream api

Metanit java stream api

Операции сведения представляют терминальные операции, которые возвращают некоторое значение — результат операции. В Stream API есть ряд операций сведения.

count

Метод count() возвращает количество элементов в потоке данных:

import java.util.stream.Stream; import java.util.Optional; import java.util.*; public class Program < public static void main(String[] args) < ArrayListnames = new ArrayList(); names.addAll(Arrays.asList(new String[])); System.out.println(names.stream().count()); // 4 // количество элементов с длиной не больше 3 символов System.out.println(names.stream().filter(n->n.length() <=3).count()); // 3 >>

findFirst и findAny

Метод findFirst() извлекает из потока первый элемент, а findAny() извлекает случайный объект из потока (нередко так же первый):

ArrayList names = new ArrayList(); names.addAll(Arrays.asList(new String[])); Optional first = names.stream().findFirst(); System.out.println(first.get()); // Tom Optional any = names.stream().findAny(); System.out.println(first.get()); // Tom

allMatch, anyMatch, noneMatch

Еще одна группа операций сведения возвращает логическое значение true или false:

  • boolean allMatch(Predicate predicate) : возвращает true, если все элементы потока удовлетворяют условию в предикате
  • boolean anyMatch(Predicate predicate) : возвращает true, если хоть один элемент потока удовлетворяют условию в предикате
  • boolean noneMatch(Predicate predicate) : возвращает true, если ни один из элементов в потоке не удовлетворяет условию в предикате

Пример использования функций:

import java.util.stream.Stream; import java.util.Optional; import java.util.ArrayList; import java.util.Arrays; public class Program < public static void main(String[] args) < ArrayListnames = new ArrayList(); names.addAll(Arrays.asList(new String[])); // есть ли в потоке строка, длина которой больше 3 boolean any = names.stream().anyMatch(s->s.length()>3); System.out.println(any); // true // все ли строки имеют длину в 3 символа boolean all = names.stream().allMatch(s->s.length()==3); System.out.println(all); // false // НЕТ ЛИ в потоке строки "Bill". Если нет, то true, если есть, то false boolean none = names.stream().noneMatch(s->s=="Bill"); System.out.println(none); // true > >

min и max

Методы min() и max() возвращают соответственно минимальное и максимальное значение. Поскольку данные в потоке могут представлять различные типы, в том числе сложные классы, то в качестве параметра в эти методы передается объект интерфейса Comparator, который указывает, как сравнивать объекты:

Optional min(Comparator comparator) Optional max(Comparator comparator)

Оба метода возвращают элемент потока (минимальный или максимальный), обернутый в объект Optional.

Например, найдем минимальное и максимальное число в числовом потоке:

import java.util.stream.Stream; import java.util.Optional; import java.util.ArrayList; import java.util.Arrays; public class Program < public static void main(String[] args) < ArrayListnumbers = new ArrayList(); numbers.addAll(Arrays.asList(new Integer[])); Optional min = numbers.stream().min(Integer::compare); Optional max = numbers.stream().max(Integer::compare); System.out.println(min.get()); // 1 System.out.println(max.get()); // 9 > >

Интерфейс Comparator — это функциональный интерфейс, который определяет один метод compare, принимающий два сравниваемых объекта и возвращающий число (если первый объект больше, возвращается положительное число, иначе возвращается отрицательное число). Поэтому вместо конкретной реализации компаратора мы можем передать лямбда-выражение или метод, который соответствует методу compare интерфейса Comparator. Поскольку сравниваются числа, то в метод передается в качестве компаратора статический метод Integer.compare() .

При этом методы min и max возвращают именно Optional, и чтобы получить непосредственно результат операции из Optional, необходимо вызвать метод get() .

Рассмотрим более сложный случай, когда нам надо сравнивать более сложные объекты:

import java.util.stream.Stream; import java.util.Optional; import java.util.ArrayList; import java.util.Arrays; public class Program < public static void main(String[] args) < ArrayListphones = new ArrayList(); phones.addAll(Arrays.asList(new Phone[]< new Phone("iPhone 8", 52000), new Phone("Nokia 9", 35000), new Phone("Samsung Galaxy S9", 48000), new Phone("HTC U12", 36000) >)); Phone min = phones.stream().min(Phone::compare).get(); Phone max = phones.stream().max(Phone::compare).get(); System.out.printf("MIN Name: %s Price: %d \n", min.getName(), min.getPrice()); System.out.printf("MAX Name: %s Price: %d \n", max.getName(), max.getPrice()); > > class Phone < private String name; private int price; public Phone(String name, int price)< this.name=name; this.price=price; >public static int compare (Phone p1, Phone p2) < if(p1.getPrice() >p2.getPrice()) return 1; return -1; > public String getName() < return name; >public int getPrice() < return price;>>

В данном случае мы находим минимальный и максимальный объект Phone: фактически объекты с максимальной и минимальной ценой. Для определения функциональности сравнения в классе Phone реализован статический метод compare , который соответствует сигнатуре метода compare интерфейса Comparator. И в методах min и max применяем этот статический метод для сравнения объектов.

MIN Name: Nokia 9 Price: 35000 MAX Name: iPhone 8 Price: 52000

Источник

Metanit java stream api

Для создания потока данных можно применять различные методы. В качестве источника потока мы можем использовать коллекции. В частности, в JDK 8 в интерфейс Collection , который реализуется всеми классами коллекций, были добавлены два метода для работы с потоками:

  • default Stream stream : возвращается поток данных из коллекции
  • default Stream parallelStream : возвращается параллельный поток данных из коллекции

Так, рассмотрим пример с ArrayList:

import java.util.stream.Stream; import java.util.*; public class Program < public static void main(String[] args) < ArrayListcities = new ArrayList(); Collections.addAll(cities, "Париж", "Лондон", "Мадрид"); cities.stream() // получаем поток .filter(s->s.length()==6) // применяем фильтрацию по длине строки .forEach(s->System.out.println(s)); // выводим отфильтрованные строки на консоль > >

Здесь с помощью вызова cities.stream() получаем поток, который использует данные из списка cities. С помощью каждой промежуточной операции, которая применяется к потоку, мы также можем получить поток с учетом модификаций. Например, мы можем изменить предыдущий пример следующим образом:

ArrayList cities = new ArrayList(); Collections.addAll(cities, "Париж", "Лондон", "Мадрид"); Stream citiesStream = cities.stream(); // получаем поток citiesStream = citiesStream.filter(s->s.length()==6); // применяем фильтрацию по длине строки citiesStream.forEach(s->System.out.println(s)); // выводим отфильтрованные строки на консоль

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

citiesStream.forEach(s->System.out.println(s)); // терминальная операция употребляет поток long number = citiesStream.count(); // здесь ошибка, так как поток уже употреблен System.out.println(number); citiesStream = citiesStream.filter(s->s.length()>5); // тоже нельзя, так как поток уже употреблен

Фактически жизненный цикл потока проходит следующие три стадии:

  1. Создание потока
  2. Применение к потоку ряда промежуточных операций
  3. Применение к потоку терминальной операции и получение результата

Кроме вышерассмотренных методов мы можем использовать еще ряд способов для создания потока данных. Один из таких способов представляет метод Arrays.stream(T[] array) , который создает поток данных из массива:

Stream citiesStream = Arrays.stream(new String[]) ; citiesStream.forEach(s->System.out.println(s)); // выводим все элементы массива

Для создания потоков IntStream, DoubleStream, LongStream можно использовать соответствующие перегруженные версии этого метода:

IntStream intStream = Arrays.stream(new int[]); intStream.forEach(i->System.out.println(i)); LongStream longStream = Arrays.stream(new long[]); longStream.forEach(l->System.out.println(l)); DoubleStream doubleStream = Arrays.stream(new double[] ); doubleStream.forEach(d->System.out.println(d));

И еще один способ создания потока представляет статический метод of(T..values) класса Stream:

Stream citiesStream =Stream.of("Париж", "Лондон", "Мадрид"); citiesStream.forEach(s->System.out.println(s)); // можно передать массив String[] cities = ; Stream citiesStream2 =Stream.of(cities); IntStream intStream = IntStream.of(1,2,4,5,7); intStream.forEach(i->System.out.println(i)); LongStream longStream = LongStream.of(100,250,400,5843787,237); longStream.forEach(l->System.out.println(l)); DoubleStream doubleStream = DoubleStream.of(3.4, 6.7, 9.5, 8.2345, 121); doubleStream.forEach(d->System.out.println(d));

Источник

Metanit java stream api

Ряд методов Stream API возвращают подпотоки или объединенные потоки на основе уже имеющихся потоков. Рассмотрим эти методы.

takeWhile

Метод takeWhile() выбирает из потока элементы, пока они соответствуют условию. Если попадается элемент, который не соответствует условию, то метод завершает свою работу. Выбранные элементы возвращаются в виде потока.

import java.util.stream.Stream; public class Program < public static void main(String[] args) < Streamnumbers = Stream.of(-3, -2, -1, 0, 1, 2, 3, -4, -5); numbers.takeWhile(n -> n < 0) .forEach(n ->System.out.println(n)); > >

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

При этом несмотря на то, что в потоке больше отрицательных чисел, но метод завершает работу, как только обнаружит первое число, которое не соответствует условию. В этом и состоит отличие, например, от метода filter() .

Чтобы в данном случае охватить все элементы, которые меньше нуля, поток следует предварительно отсортировать:

Stream numbers = Stream.of(-3, -2, -1, 0, 1, 2, 3, -4, -5); numbers.sorted().takeWhile(n -> n < 0) .forEach(n ->System.out.println(n));

Консольный вывод программы:

dropWhile

Метод dropWhile() выполняет обратную задачу — он пропускает элементы потока, которые соответствуют условию до тех пор, пока не встретит элемент, который НЕ соответствует условию:

Stream numbers = Stream.of(-3, -2, -1, 0, 1, 2, 3, -4, -5); numbers.sorted().dropWhile(n -> n < 0) .forEach(n ->System.out.println(n));

Консольный вывод программы:

concat

Статический метод concat() объединяет элементы двух потоков, возвращая объединенный поток:

import java.util.stream.Stream; public class Program < public static void main(String[] args) < Streampeople1 = Stream.of("Tom", "Bob", "Sam"); Stream people2 = Stream.of("Alice", "Kate", "Sam"); Stream.concat(people1, people2).forEach(n -> System.out.println(n)); > >
Tom Bob Sam Alice Kate Sam

distinct

Метод distinct() возвращает только ункальные элементы в виде потока:

Stream people = Stream.of("Tom", "Bob", "Sam", "Tom", "Alice", "Kate", "Sam"); people.distinct().forEach(p -> System.out.println(p));

Источник

Читайте также:  Unit test python order
Оцените статью