Java 8 stream API

Stream API это вершина нововведений в java 8: используя функциональные интерфейсы и лямбда-выражения Stream API предоставляет функциональный подход к обработке наборов данных. Говоря проще, Stream API позволяет решать классические задачи по обработке наборов данных более гибко и элегантно:

    public final String oldSchoolGreet() {
        List<String> result = new ArrayList<>();
        for (String s: LONG_WELCOME) {
            if (s.length() == WORD_LENGTH) {
                result.add(s);
            }
        }


        Iterator<String> it = result.iterator();
        StringBuilder buf = new StringBuilder();
        buf.append(it.next());
        while (it.hasNext()) {
            buf.append(", ");
            buf.append(it.next());
        }


        return buf.toString();
    }
    public final String greet() {
        return LONG_WELCOME
                .stream()
                .filter(s -> s.length() == WORD_LENGTH)
                .collect(Collectors.joining(", "));
    }

Вызов stream() на Iterable создаёт объект Stream, у которого есть два типа методов — конвейерные, как filter() и терминальные, как collect(). Отличаются тем, что конвейерные методы возвращают тот же самый объект Stream, а терминальные методы возвращают любой другой тип. Истинные различия конечно же глубже: конвейерные методы не выполняются сразу, а только конфигурируют конвейер обработки, в то время как терминальные методы запускают конвейер. Из этого следует, что даже если сохранить объект Stream куда-нибудь, повторное его использование после вызова терминальной функции не допускается:

    @Test(expected = IllegalStateException.class)
    public void testClosedStream() {
        Stream<String> s = Arrays.stream(new String[]{"TEST", "STREAM"});
        s.count();


        s.noneMatch(String::isEmpty);
    }

Типичное использование

Поиск в коллекции элемента, удовлетворяющего условию:

    public final boolean haveHello() {
        return LONG_WELCOME.stream().anyMatch(s->s.equals("Hello"));
    }

Получение коллекции свойств из коллекции объектов:

    public Collection<String> getLogins() {
        return data
                .stream()
                .map(User::getLogin)
                .collect(Collectors.toList());
    }

map() применяет лямбда-выражение к Stream и возвращает Stream такого типа, который возвращает лямбда-выражение. Поскольку это конвейерная функция, вызовов map() может быть несколько. collect() это терминальная функция, собирающая результат обработки в один объект. В данном случае используется стандартный коллектор, создающий список.

Построение коллекции из элементов другой коллекции, удовлетворяющей условию:

    public Collection<String> highLevelLogins() {
        return data
                .stream()
                .filter(u->u.getAccessLevel()>1)
                .map(User::getLogin)
                .collect(Collectors.toSet());
    }

filter() мы уже видели раньше, эта функция применяет лямбда-выражение к элементам Stream, возвращая Stream, состоящий только из элементов, для которых выражение вернуло true.

Продолжение следует.

Скачать код примера

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

Ваш адрес email не будет опубликован. Обязательные поля помечены *