英文:
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<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(); // <-------
                    ...      
			});
}
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<DoubleStream, OptionalDouble> type methods, so:
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()));
                    ...      
            });
}
答案2
得分: 3
方法.average和.max都是Function<DoubleStream, OptionalDouble>类型,你可以将它们存储在这个类型中:
Function<DoubleStream, OptionalDouble> avg = DoubleStream::average; // 例如 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);
英文:
The methods .average and .max are both Function<DoubleStream, OptionalDouble> , you can so store them in this type :
Function<DoubleStream, OptionalDouble> avg = DoubleStream::average; // ie ds -> ds.average()
Function<DoubleStream, OptionalDouble> mx = DoubleStream::max;
The use it as a parameter and use .apply with the DoubleStream as parameter
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));
            });
}
So the calls will be
Function<DoubleStream, OptionalDouble> avg = ds -> ds.average();
Function<DoubleStream, OptionalDouble> mx = DoubleStream::max;
method(...,10, avg);
method(...,10, mx);
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论