Промежуточные операции Stream API

Вернуться назад

7 апреля 2019

Все методы Stream API можно разделить на две группы: промежуточные и терминальные (конечные). Промежуточные операции следует воспринимать как «отложенные», т.е. они не меняют сами данные, а только задают правила их изменения. А терминальные как раз инициируют всю цепочку преобразований и возвращают модифицированные данные.

Рассмотрим промежуточные операции. Все промежуточные операции возвращают типизированный интерфейс Stream<>.

Преобразование

Любое изменение исходного элемента можно делать с помощью метода map(). В качестве параметра метод принимает лямбда-выражение.

Stream.of(123456)
        .map(n -> n * 10// умножает каждый элемент на 10

Stream.of("apple""orange")
        .map(String::toUpperCase) // преобразует буквы в каждом слове в верхний регистр

Во втором случае мы воспользовались краткой записью лямбда-выражения через method reference.

Фильтрация

Отсеивание части объектов можно сделать с помощью метода filter().

Stream.of(123456)
        .filter(n -> n > 3// оставляет только те числа, которые больше 3

Доступ к элементу

Если требуется получить доступ к элементу, никак его при этом не меняя, нам поможет метод peek(). Например, в целях логирования мы хотим вывести значение элемента в консоль.

Stream.of(123456)
        .peek(System.out::println)

Удаление дублей

Если в стриме несколько элементов имеют одинаковые значения, а вы хотите получить только уникальные, используйте метод distinct().

Stream.of(22323322)
        .distinct() // в результате останется только два элемента: [2, 3]

Сортировка

Для сортировки используйте метод sorted(). По умолчанию он использует «натуральный порядок», т.е. сортировку по возрастанию.

Stream.of(213546)
        .sorted() // получим [1, 2, 3, 4, 5, 6]

Перегруженная версия этого метода принимает интерфейс Comparator, поэтому вы можете задать свои собственные правила сортировки или воспользоваться готовыми. Приведённый выше пример равносилен следующему:

Stream.of(213546)
        .sorted(Comparator.naturalOrder())) // получим [1, 2, 3, 4, 5, 6]

Нетрудно догадаться, что обратную сортировку можно задать таким образом:

Stream.of(213546)
        .sorted(Comparator.reverseOrder()) // получим [6, 5, 4, 3, 2, 1]

Ограничение по количеству элементов

Для получения первых N элементов используйте метод limit(). В данном случае мы берём первые 3 элемента:

Stream.of(123456)
        .limit(3// [1, 2, 3]

Пропуск первых элементов

Чтобы пропустить нужное количество первых элементов, используйте метод skip(). Здесь мы пропускаем первые 4 элемента и получаем оставшиеся два:

Stream.of(123456)
        .skip(4// [5, 6]

Обратите внимание, что комбинация методов limit() и skip() позволяет организовать постраничный вывод информации. Например, в пользовательском интерфейсе мы отображаем по две записи на странице. Тогда, если у нас запросят вторую страницу, то выражение будет выглядеть так:

Stream.of(123456)
        .skip(2)
        .limit(2// [3, 4]

Разворачивание многомерных структур

Предположим, у вас есть многомерная структура (двумерный массив элементов типа Integer) и вы хотите его развернуть (сделать «плоским»), просто помещая каждый подмассив в конец результирующего. В этом нам поможет метод flatMap():

Integer[][] array2d = new Integer[][]{{12}, {34}};
Stream<Integer> stream =
        Arrays.stream(array2d).flatMap(Arrays::stream); // [1, 2, 3, 4]

Выводы

В этой статье мы рассмотрели на примерах промежуточные методы Stream API, а во второй части рассмотрим уже терминальные (конечные) методы.

Тэги: Collections, Java 8, Stream API.



Добавить комментарий

Ваше имя:
Текст комментария: