Методы Stream API
Методы Stream API делятся на две категории::
- Оконечные (terminal)
- Промежуточные (intermediate)
- Без сохранения состояния (stateless)
- С сохранением состояния (stateful)
1. Terminal методы
Оконечные операции завершают работу со Stream, потребляя его. После выполнения терминальной операции повторное использование потока невозможно.
Примеры терминальных методов:
forEach()
collect()
count()
min()
,max()
findFirst()
,findAny()
allMatch()
,anyMatch()
,noneMatch()
reduce()
toArray()
Пример:
int[] digits = {0, 1, 2, 3, 4 , 5, 6, 7, 8, 9};
IntStream s = IntStream.of(digits);
long n = s.count();
System.out.println(s.findFirst()); // An exception is thrown
Чтобы использовать поток повторно, его нужно пересоздать:
int[] digits = {0, 1, 2, 3, 4 , 5, 6, 7, 8, 9};
long n = IntStream.of(digits).count();
System.out.println(IntStream.of(digits).findFirst()); // OK
Пример использования нескольких операций:
public class StreamDemo1 {
public static void main(String[] args) {
Stream.of("sun", "pool", "beach", "kid", "island", "sea", "sand")
.map(String::length)
.filter(i -> i > 3)
.limit(2)
.forEach(System.out::println);
}
}
public class StreamDemo2 {
public static void main(String[] args) {
Stream.of("sun", "pool", "beach", "kid", "island", "sea", "sand")
.map(str -> {
System.out.println("Mapping: " + str);
return str.length();
})
.filter(i -> {
System.out.println("Filtering: " + i);
return i > 3;
})
.limit(2)
.forEach(System.out::println);
}
}
public class StreamDemo7 {
public static void main(String[] args) {
List<String> words = Arrays.asList("hello", null, "");
words.stream()
.filter(t -> t != null && !t.isEmpty())
.forEach(System.out::println);
}
}
public class StreamDemo8 {
public static void main(String[] args) {
List<String> words = Arrays.asList("hello", null, "world","hi");
words.stream()
.filter(Objects::nonNull)
.sorted()
.distinct()
.forEach(System.out::println);
}
}
Полезно использовать Optional
для обработки результатов min()
и findFirst()
:
public class StreamDemo3 {
public static void main(String[] args) {
List<String> strings = Arrays.asList("Stream",
"Operations", "on", "Collections");
Optional<String> optional = strings.stream()
.min(Comparator.comparing(String::length));
optional.ifPresent(System.out::println);
}
}
Операции sum()
, average()
применимы к числовым потокам:
public class StreamDemo4 {
public static void main(String[] args) {
System.out.println(
IntStream.of(28,4,91,30).sum()
);
System.out.println(
IntStream.of(28,4,91,30).average()
);
}
}
Метод collect()
Метод collect()
используется для преобразования потока в коллекции (List
, Set
, Map
и др.).
Пример:
public class StreamDemo5 {
public static void main(String[] args) {
List<String> phones = 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<String> filteredPhones = phones.stream()
.filter(s -> s.length() < 10)
.collect(Collectors.toList());
System.out.println(filteredPhones);
}
}
Преобразование в Map:
public class StreamDemo9 {
public static void main(String[] args) {
Stream<ColorBox> stream = Stream.of(new ColorBox(1, 1, 1, "red"),
new ColorBox(2, 2, 2, "green"),
new ColorBox(3, 3, 3, "blue"),
new ColorBox(4, 4, 4, "black"));
Map<String, ColorBox> map = stream
.collect(Collectors.toMap(box -> box.color, box -> box));
map.forEach((k, v) -> System.out.println(k + " " + v));
}
}
Collectors.groupingBy()
Группировка элементов по признаку:
Map<Integer, List<Integer>> grouped = Stream.of(2, 34, 54, 23)
.collect(Collectors.groupingBy(i -> i / 10 * 10));
Подсчет элементов в группах:
Map<Integer, Long> counted = Stream.of(2, 34, 54, 23)
.collect(Collectors.groupingBy(i -> i / 10 * 10, Collectors.counting()));
2. Intermediate (промежуточные) методы
Промежуточные методы возвращают новый поток, на который можно навешивать следующие операции. Все промежуточные методы являются lazy — они выполняются только после вызова терминальной операции.
Метод | Тип | Описание |
---|---|---|
filter() | Stateless | Фильтрует элементы по предикату |
map() | Stateless | Преобразует каждый элемент |
flatMap() | Stateless | Плоское отображение вложенных структур |
distinct() | Stateful | Убирает дубликаты |
sorted() | Stateful | Сортирует элементы |
limit() | Stateful | Ограничивает количество |
skip() | Stateful | Пропускает первые n элементов |
peek() | Stateless | Выполняет действие для отладки |
parallel() | - | Делает поток параллельным |
sequential() | - | Делает поток последовательным |
unordered() | - | Убирает порядок |
Stateless vs stateful
Stateless операции — не зависят от других элементов (например, map
, filter
).
Stateful операции — требуют информации о других элементах (например, distinct
, sorted
).
Пример с filter()
и sorted()
:
words.stream()
.filter(Objects::nonNull)
.sorted()
.distinct()
.forEach(System.out::println);

Зарегистрируйтесь или войдите, чтобы иметь возможность оставить комментарий.