Factorize code where the only differences are Stream reduction operation.

huangapple go评论76阅读模式
英文:

Factorize code where the only differences are Stream reduction operation

问题

我有一堆方法,唯一的区别是流缩减操作:

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(); // <-------
                    ...      
			});
}

如何将这段代码因式分解并拥有参数化的缩减操作(最小、最大、平均、总和)?

提前谢谢。

英文:

I have a bunch of methods where the only difference is a Stream reduction operation :

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

How to factorize this code and have a parametrized reduction operation (min, max, average, sum) ?

Thanks in advance.

答案1

得分: 3

以下是翻译好的部分:

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()));
                    ...      
            });
}
英文:

Both average() and max() are Function&lt;DoubleStream, OptionalDouble&gt; type methods, so:

static Stream&lt;TimeValues&gt; avg(Stream&lt;TimeValues&gt; data, int batchSize) {
    return reduce(data, batchSize, DoubleStream::average);
}

static Stream&lt;TimeValues&gt; max(Stream&lt;TimeValues&gt; data, int batchSize) {
    return reduce(data, batchSize, DoubleStream::max);
}

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

答案2

得分: 3

方法.average.max都是Function<DoubleStream, OptionalDouble>类型,你可以将它们存储在这个类型中:

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

然后将其作为参数使用,并在参数中使用.applyDoubleStream

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);
英文:

The methods .average and .max are both Function&lt;DoubleStream, OptionalDouble&gt; , you can so store them in this type :

Function&lt;DoubleStream, OptionalDouble&gt; avg = DoubleStream::average; // ie ds -&gt; ds.average()
Function&lt;DoubleStream, OptionalDouble&gt; mx = DoubleStream::max;

The use it as a parameter and use .apply with the DoubleStream as parameter

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

So the calls will be

Function&lt;DoubleStream, OptionalDouble&gt; avg = ds -&gt; ds.average();
Function&lt;DoubleStream, OptionalDouble&gt; mx = DoubleStream::max;

method(...,10, avg);
method(...,10, mx);

huangapple
  • 本文由 发表于 2020年5月2日 18:47:12
  • 转载请务必保留本文链接:https://go.coder-hub.com/61558098.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定