Вызовы потоковых операций Java - PullRequest
0 голосов
/ 10 ноября 2018

Может ли кто-нибудь указать на официальную документацию Java, которая описывает, сколько раз Stream будет вызывать каждую промежуточную операцию «без вмешательства и отсутствия состояния» для каждого элемента.

Например:

Arrays.asList("1", "2", "3", "4").stream()
        .filter(s -> check(s))
        .forEach(s -> System.out.println(s));

public boolean check(Object o) {
    return true;
} 

Вышеупомянутое в настоящее время вызовет check метод 4 раза.

Возможно ли, что в текущих или будущих версиях JDK метод check выполняется больше или меньше раз, чем количество элементов в потоке , созданном из List или любого другого стандартаJava API?

Ответы [ 2 ]

0 голосов
/ 10 ноября 2018

С документация :

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

В силу этого, поскольку filter является промежуточной операцией, которая создает новый Stream как часть своей операции, из-за своей лени он будет вызывать предикат фильтра только один раз на элемент как часть его восстановления потока.

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

0 голосов
/ 10 ноября 2018

Это не имеет отношения к источнику потока, а скорее к терминальной работе и оптимизации, выполненной в самой реализации потока. Например:

Stream.of(1,2,3,4)
      .map(x -> x + 1)
      .count();

Поскольку java-9, map не будет выполняться ни разу.

Или:

 someTreeSet.stream()
            .sorted()
            .findFirst();

sorted может вообще не выполняться, поскольку источником является TreeSet и получение первого элемента тривиально, но если это реализовано внутри потокового API или нет, это другой вопрос.

Так что настоящий ответ здесь - это зависит, но я не могу представить одну операцию, которая выполнялась бы больше, чем количество элементов в источнике.

...