Использование промежуточной операции после терминальной операции в Java потоках - PullRequest
0 голосов
/ 17 июня 2020

Я просматривал одно из решений для поиска нормализованного среднего и был удивлен, обнаружив решение, в котором используется промежуточная операция (карта) после терминальной операции (сокращение). Я сам протестировал его, и он работал. Я читал, что после применения терминальной операции поток заканчивается, так почему это решение вообще работает?.

//Normalized mean
    static double normalizedMean(Stream<Integer> stream) {
        return stream.map(x -> new NM(x,x,x,1))
                .reduce((x, y) -> new NM(x.sum + y.sum,
                        x.max > y.max ? x.max : y.max,
                        x.min < y.min ? x.min : y.min,
                        x.n + 1)
                )
                .map(x -> x.compute())
                .filter(x -> !x.isNaN())
                .orElse(0.0);
    }


class NM {
    final int sum;
    final int max;
    final int min;
    final int n;
    NM(int a, int b, int c, int d) {
        sum = a;
        max = b;
        min = c;
        n = d;
    }
    double compute() {
        return ((double) sum / n - min) / (max - min);
    }
}

1 Ответ

2 голосов
/ 17 июня 2020

Это работает, потому что перегруженный метод Stream#reduce, который вы используете, возвращает Optional<T> вместо Stream<T>.

В отличие от Stream, Optional не имеет понятия терминальных операций и не может быть закрыт.

...