← Назад к вопросам
Приведи пример промежуточных операций в Stream API
2.0 Middle🔥 201 комментариев
#Другое
Комментарии (1)
🐱
deepseek-v3.2PrepBro AI6 апр. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Примеры промежуточных операций в Stream API
Промежуточные операции в Stream API — это операции, которые преобразуют поток и возвращают новый поток, позволяя строить цепочки обработки данных. Они ленивые — выполняются только при вызове терминальной операции. Вот основные категории и примеры.
1. Фильтрация и выборка
List<String> names = Arrays.asList("Анна", "Иван", "Мария", "Петр", "Алексей");
// filter: отбирает элементы по условию
List<String> startWithA = names.stream()
.filter(name -> name.startsWith("А"))
.collect(Collectors.toList()); // ["Анна", "Алексей"]
// distinct: удаляет дубликаты
List<Integer> numbers = Arrays.asList(1, 2, 2, 3, 4, 4, 5);
List<Integer> unique = numbers.stream()
.distinct()
.collect(Collectors.toList()); // [1, 2, 3, 4, 5]
2. Преобразование элементов
// map: преобразует каждый элемент
List<String> upperNames = names.stream()
.map(String::toUpperCase)
.collect(Collectors.toList()); // ["АННА", "ИВАН", "МАРИЯ"...]
// flatMap: "разворачивает" вложенные структуры
List<List<String>> nestedList = Arrays.asList(
Arrays.asList("a", "b"),
Arrays.asList("c", "d")
);
List<String> flat = nestedList.stream()
.flatMap(Collection::stream)
.collect(Collectors.toList()); // ["a", "b", "c", "d"]
3. Ограничение и пропуск элементов
List<Integer> nums = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8);
// limit: ограничивает количество элементов
List<Integer> firstThree = nums.stream()
.limit(3)
.collect(Collectors.toList()); // [1, 2, 3]
// skip: пропускает первые N элементов
List<Integer> afterThird = nums.stream()
.skip(3)
.collect(Collectors.toList()); // [4, 5, 6, 7, 8]
4. Сортировка
// sorted: сортировка элементов
List<String> sortedNames = names.stream()
.sorted()
.collect(Collectors.toList()); // ["Алексей", "Анна", "Иван", "Мария", "Петр"]
// sorted с компаратором
List<String> byLength = names.stream()
.sorted(Comparator.comparingInt(String::length))
.collect(Collectors.toList()); // ["Иван", "Петр", "Анна", "Мария", "Алексей"]
5. Отладка и просмотр элементов
// peek: выполняет действие для каждого элемента без изменения
List<String> processed = names.stream()
.filter(name -> name.length() > 4)
.peek(name -> System.out.println("Отфильтровано: " + name))
.map(String::toUpperCase)
.collect(Collectors.toList());
Комбинированный пример
Вот практический пример, демонстрирующий цепочку промежуточных операций:
List<Employee> employees = Arrays.asList(
new Employee("Иван", 25, 50000),
new Employee("Мария", 30, 60000),
new Employee("Алексей", 25, 55000),
new Employee("Ольга", 35, 70000)
);
List<String> result = employees.stream()
// 1. Фильтрация: возраст < 30
.filter(emp -> emp.getAge() < 30)
// 2. Сортировка: по зарплате по убыванию
.sorted(Comparator.comparingInt(Employee::getSalary).reversed())
// 3. Преобразование: в строки
.map(emp -> emp.getName() + " - " + emp.getSalary())
// 4. Пропуск первого
.skip(1)
// 5. Ограничение вывода
.limit(2)
.collect(Collectors.toList());
// Результат: ["Алексей - 55000", "Иван - 50000"]
Важные особенности промежуточных операций:
- Ленивость: Вычисления происходят только при вызове терминальной операции
- Без состояния: Большинство операций (
filter,map) не зависят от предыдущих элементов - С состоянием: Некоторые операции (
sorted,distinct) требуют знания всех элементов - Конвейерность: Операции объединяются в конвейер, минимизируя проходы по данным
Эти операции составляют основу функционального стиля обработки коллекций в Java, делая код более декларативным и читаемым. Правильное комбинирование промежуточных операций позволяет эффективно решать сложные задачи обработки данных с минимальным написанием кода.