Stream API
Stream API — это новый способ работать со структурами данных в функциональном стиле. Stream (поток) API (описание способов, которыми одна компьютерная программа может взаимодействовать с другой программой) — это по своей сути поток данных. Сам термин «поток» довольно размыт в программировании в целом и в Java в частности.
С появлением Java 8 Stream API позволило программистам писать существенно короче то, что раньше занимало много строк кода, а именно — упростить работу с наборами данных, в частности, упростить операции фильтрации, сортировки и другие манипуляции с данными. Если у вас промежуточных операций нет, часто можно и нужно обойтись без стрима, иначе код будет сложнее чем без потока.
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.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)) , которое в свою очередь проходит по всем элементам переданной ему коллекции и выводит её)
- Обработка не начнётся до тех пор, пока не будет вызван терминальный оператор. list.stream().filter(s -> s > 5) (не возьмёт ни единого элемента из списка);
- Экземпляр, стрима нельзя использовать более одного раза =( ;
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));
- 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 преобразует в список потоков (точнее
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
- 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 ]