Факторизовать код, где единственными отличиями являются операции сокращения потока - PullRequest
2 голосов
/ 02 мая 2020

У меня есть несколько методов, единственное отличие которых состоит в операции сокращения потока:

static Stream<TimeValues> avg(Stream<TimeValues> data, int batchSize) {
    return data
            .collect(SlidingCollector.batch(batchSize))
            .stream()
            .map(tvl -> {
                    OptionalDouble od = tvl.stream()
                    ...
                        .mapToDouble(tv -> tv.doubleValue())
                        .average(); // <-------
                    ...      
            });
}
static Stream<TimeValues> max(Stream<TimeValues> data, int batchSize) {
    return data
            .collect(SlidingCollector.batch(batchSize))
            .stream()
            .map(tvl -> {
                    OptionalDouble od = tvl.stream()
                    ...
                        .mapToDouble(tv -> tv.doubleValue())
                        .max(); // <-------
                    ...      
            });
}

Как разложить этот код и выполнить параметризованную операцию сокращения (мин, макс, среднее, сумма )?

Заранее спасибо.

Ответы [ 2 ]

4 голосов
/ 02 мая 2020

Методы .average и .max оба Function<DoubleStream, OptionalDouble>, вы можете хранить их в таком виде:

Function<DoubleStream, OptionalDouble> avg = DoubleStream::average; // ie ds -> ds.average()
Function<DoubleStream, OptionalDouble> mx = DoubleStream::max;

Используйте его в качестве параметра и используйте .apply с DoubleStream как параметр

static Stream<TimeValues> method(Stream<TimeValues> data, int batchSize, 
                                 Function<DoubleStream, OptionalDouble> fct) {
    return data
            .collect(SlidingCollector.batch(batchSize))
            .stream()
            .map(tvl -> {
                OptionalDouble od = fct.apply(tvl.stream().mapToDouble(Number::doubleValue));
            });
}

Так что звонки будут

Function<DoubleStream, OptionalDouble> avg = ds -> ds.average();
Function<DoubleStream, OptionalDouble> mx = DoubleStream::max;

method(...,10, avg);
method(...,10, mx);
4 голосов
/ 02 мая 2020

Оба average() и max() являются методами типа Function<DoubleStream, OptionalDouble>, поэтому:

static Stream<TimeValues> avg(Stream<TimeValues> data, int batchSize) {
    return reduce(data, batchSize, DoubleStream::average);
}

static Stream<TimeValues> max(Stream<TimeValues> data, int batchSize) {
    return reduce(data, batchSize, DoubleStream::max);
}

private static Stream<TimeValues> reduce(Stream<TimeValues> data, int batchSize,
                                         Function<DoubleStream, OptionalDouble> reducer) {
    return data
            .collect(SlidingCollector.batch(batchSize))
            .stream()
            .map(tvl -> {
                    OptionalDouble od = reducer.apply(tvl.stream()
                    ...
                        .mapToDouble(tv -> tv.doubleValue()));
                    ...      
            });
}
...