Промежуточные методы Stream
Промежуточные методы
Мы разобрались с большинством методов создания стрима. Теперь давайте рассмотрим методы для обработки элементов.
filter(Predicate)Этот метод используется для создания нового потока, включающего только элементы, которые удовлетворяют определенному условию. В качестве аргумента метод принимает функциональный интерфейс Predicate, задающий условие фильтрации.Вот пример использования метода filter() для создания нового потока, который включает только четные числа из списка целых чисел.List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
Stream<Integer> evenNumbersStream = numbers.stream() .filter(n -> n % 2 == 0);
evenNumbersStream.forEach(System.out::println); // prints 2, 4, 6, 8, 10
map(Function)Метод map() принимает в качестве аргумента функциональный интерфейс Function, задающий преобразование, применяемое к каждому элементу. Возвращаемый поток содержит преобразованные элементы.Метод map() возвращает новый поток. Он не изменяет исходный поток и коллекцию. Обычно он используется для выполнения операций, таких как преобразование элементов из одного типа в другой.List<String> words = Arrays.asList("apple", "banana", "orange", "peach");
Stream<Integer> lengthsStream = words.stream().map(String::length);
lengthsStream.forEach(System.out::println);
// prints 5, 6, 6, 5В данном примере мы с помощью map() преобразовали строку в количество символов в строке, используя короткую запись лямбды (String::length), так называемую ссылку на метод.
flatMap()Метод flatMap() используется для создания одного потока из множества потоков. Он принимает функцию в качестве аргумента, которая применяется к каждому элементу исходного потока. Эта функция принимает элемент исходного потока и возвращает новый поток.
List<List<Integer>> listOfLists = Arrays.asList(Arrays.asList(1, 2, 3),Arrays.asList(4, 5, 6),Arrays.asList(7, 8, 9));Stream<Integer> flattenedStream = listOfLists.stream().flatMap(Collection::stream);flattenedStream.forEach(System.out::println); // prints 1, 2, 3, 4, 5, 6, 7, 8, 9
В данном примере мы начинаем со списка списков целых чисел и создаем поток с помощью метода stream(). Затем мы используем метод flatMap() для создания нового потока, включающего все целые числа из вложенных списков, путем применения метода stream() к каждому из вложенных списков. Наконец, мы используем метод forEach() для вывода каждого элемента нового потока.
distinct()
Метод distinct() возвращает новый поток, содержащий только уникальные элементы исходного потока. Дубликаты определяются на основе их естественного порядка или с использованием переданного компаратора.
Вот пример, в котором функция distinct() используется для удаления дубликатов из потока целых чисел:
List<Integer> numbers = Arrays.asList(1, 2, 3, 2, 1, 4, 5, 3, 5);List<Integer> uniqueNumbers = numbers.stream().distinct().collect(Collectors.toList());System.out.println(uniqueNumbers); // prints [1, 2, 3, 4, 5]
limit(n)
Метод limit(n) возвращает новый поток, содержащий не более n элементов исходного потока. Если исходный поток содержит меньше n элементов, новый поток будет содержать все элементы исходного потока.
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);List<Integer> limitedNumbers = numbers.stream().limit(5).collect(Collectors.toList());System.out.println(limitedNumbers); // prints [1, 2, 3, 4, 5]
skip(n)
Метод skip(n) возвращает новый поток, который содержит все элементы исходного потока, исключая первые n элементов. Если исходный поток содержит меньше n элементов, новый поток будет пустым.
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);List<Integer> skippedNumbers = numbers.stream().skip(5).collect(Collectors.toList());System.out.println(skippedNumbers); // prints [6, 7, 8, 9, 10]
sorted()
Метод sorted() создает новый поток, содержащий элементы исходного потока, отсортированные в порядке возрастания.
При вызове метода sorted() возвращается новый поток, содержащий те же элементы, что и исходный поток, но в отсортированном порядке.
List<String> names = Arrays.asList("Alice", "Bob", "Charlie", "David");List<String> sortedNames = names.stream().sorted().collect(Collectors.toList());System.out.println(sortedNames); // prints ["Alice", "Bob", "Charlie", "David"]
takeWhile(Predicate)
Метод takeWhile() создает новый поток, содержащий элементы исходного потока до тех пор, пока они удовлетворяют указанному условию. Если первый элемент потока не соответствует предикату, новый поток будет пустым.
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);List<Integer> takenNumbers = numbers.stream().takeWhile(n -> n < 5).collect(Collectors.toList());System.out.println(takenNumbers); // prints [1, 2, 3, 4]
dropWhile(Predicate)
Метод dropWhile() возвращает новый поток, который включает все элементы исходного потока, начиная с первого элемента, не удовлетворяющего указанному условию. В момент, когда предикат возвращает false, все последующие элементы из исходного потока включаются в новый поток.
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);List<Integer> droppedNumbers = numbers.stream().dropWhile(n -> n < 5).collect(Collectors.toList());System.out.println(droppedNumbers); // prints [5, 6, 7, 8, 9, 10]
peek(Consumer)
Метод peek() создает новый поток, идентичный исходному, но с дополнительной операцией, применяемой к каждому элементу при его прохождении по конвейеру потока.
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);numbers.stream().peek(System.out::println).collect(Collectors.toList());
В данном примере, метод peek() применяется к потоку чисел. Consumer, переданный в метод peek(), выводит каждый элемент на консоль. В процессе этого, каждый элемент, проходя по конвейеру потока, отображается на консоли, но сам поток остается неизменным.