Stream Api

Проработать

  1. Шпаргалка Java программиста 4. Java Stream API
  2. Немного о Stream API(Java 8)
  3. Используйте Stream API проще (или не используйте вообще)
  4. Полное руководство по Java 8 Stream API в картинках и примерах
  5. Урок 328: Java 8 p4: Streams
  6. Немного о Stream API(Java 8)
  7. The Java 8 Stream API Tutorial
  8. Java 8 Stream API или краткость - сестра таланта [GeekBrains]
  9. Перевод руководства по Stream API от Benjamin Winterberg
  10. Streams. Метод reduce (прокачанная Java)
  11. Метод reduce
  12. Java 8 Stream flatMap()
  13. Parallel Stream — не панацея или используй с умом (tutorial для начинающих)
  14. Работа с потоками, часть 3
  15. Как вызвать(переиспользовать) stream несколько раз?

Stream Api - способ работать со структурами данных в функциональном стиле. Чаще всего с помощью stream в Java 8 работают с коллекциями, но на самом деле этот механизм может использоваться и для других задач. Не работает с примитивами за исключением int, long, double для которых есть отдельные Stream.

Виды операторов:

Конвейерные(промежуточные, intermediate) операторы

Конвейерные операторы - возвращают новый Stream и не выполняются без терминального оператора.

  1. map(Function mapper) - преобразует каждый элемент стрима. Одно выходное значение из каждого входного.
  2. flatMap(Function<T, Stream <R>> mapper) - создаёт произвольное количество выходных значений(0 или больше) для каждого входного. Под капотом из каждого элемента создается новый поток и в конце все потоки создают исходный поток.
  3. filter(Predicate predicate) - фильтрует стрим, пропуская только те элементы, что проходят по условию.
  4. dropWhile(Predicate predicate) — фильтрует стрим, пропуская только те элементы, что не проходят по условию.
  5. takeWhile(Predicate predicate) — пропускает далее элементы пока условие выполняется и при первом не выполнении, больше никого не пропускает.
  6. limit(long maxSize) – ограничивает стрим по количеству элементов.
  7. skip(long n) – пропускаем n элементов.
  8. sorted() – сортировка.
  9. sorted(Comparator comparator) – сортирует стрим (сортировка как у TreeMap).
  10. distinct() - убирает повторы элементов.

Терминальные(terminal) операторы

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

  1. forEach(Consumer action) - аналог for each.
  2. count() – возвращает количество элементов стрима.
  3. reduce - позволяет выполнять агрегатные функции на всей коллекцией и возвращать один результат.
  4. collect(Collector collector) – метод собирает все элементы в список, множество или другую коллекцию, сгруппировывает элементы по какому-нибудь критерию, объединяет всё в строку и т.д.
  5. min(Comparator comparator)
  6. max(Comparator comparator)
  7. findFirst() - получить первый элемент стрима.
  8. allMatch(Predicate predicate) - возвращает true, если все элементы стрима удовлетворяют условию или false.
  9. anyMatch(Predicate predicate) - вернет true, если хотя бы один элемент стрима удовлетворяет условию predicate.
  10. noneMatch(Predicate predicate) - вернёт true, если, пройдя все элементы стрима, ни один не удовлетворил условию.

Примеры создания Stream

Примеры использования:

Проверка

var list = List.of("A", "B", "C");
var matchingElements = Stream.of("B", "C", "D")
        .anyMatch(list::contains);
        

Поиск совпадений элементов двух списков

var list = List.of("A", "B", "C");
var matchingElements = List.of("B", "C", "D")
    .stream()
    .filter(list::contains)
    .toList();
        

Поиск не совпадений элементов двух списков

var list = List.of("A", "B", "C");
var matchingElements = List.of("B", "C", "D")
    .stream()
    .filter(element -> !list.contains(element))
    .toList();
        

Нахождения процентиля(перцентиль)

var latencies = Stream.of(10, 3, 6, 7, 8, 8, 9, 13, 15, 16, 20).toList();
System.out.println(percentile(latencies, 25));
System.out.println(percentile(latencies, 50));
System.out.println(percentile(latencies, 75));
System.out.println(percentile(latencies, 100));

public static long percentile(List<Integer> latencies, double percentile) {
    int index = (int) Math.ceil(percentile / 100.0 * latencies.size());
    return latencies.get(index-1);
}
        

Нахождения процентиля(перцентиль)

var latencies = Stream.of(10, 3, 6, 7, 8, 8, 9, 13, 15, 16, 20).toList();
System.out.println(percentile(latencies, 25));
System.out.println(percentile(latencies, 50));
System.out.println(percentile(latencies, 75));
System.out.println(percentile(latencies, 100));

public static long percentile(List<Integer> latencies, double percentile) {
    int index = (int) Math.ceil(percentile / 100.0 * latencies.size());
    return latencies.get(index-1);
}
        

List to Map

var list = Stream.of("1", "2", "3").toList();
var map = list.stream().collect(Collectors.toMap(i -> i, i -> "sample"));