如何找到流的归一化平均值?
我被困在如何找到流的归一化平均值。流包含数字,我试图找到归一化的平均值。方程被归一化mean = (avg of stream - min of stream)/(max of stream - min of stream)
normalizedStream(Stream.of(1,2,3,4,5)) 会给我 0.5
public static double normalizedMean(Stream<Integer> stream) {
Integer max = max(stream);
Integer min = min(stream);
Integer sum = sum(stream);
long count = count(stream);
return (double) ((sum / count) - min) / (max - min);
}
当我这样做时,他们说流已经通过管道传输。
回答
您不能多次使用单个流,因此您必须创建流的副本,或者使用单个归约操作获取所需的所有统计数据(平均值、最大值、最小值)。
对于前一种方法,您需要知道流的来源是什么,即Supplier<Stream<Integer>>每次调用时都会为您提供一个新流get,并多次调用它:
// Rather than passing in someList.stream(), you would instead pass in someList::stream, for example
public static double normalizedMean(Supplier<Stream<Integer>> streamSupplier) {
Integer max = max(streamSupplier.get());
Integer min = min(streamSupplier.get());
Integer sum = sum(streamSupplier.get());
long count = count(streamSupplier.get());
return (double) ((sum / count) - min) / (max - min);
}
正如您可能会说的,这不是一种很好的处理方式,因为您不必要地多次迭代流。
对于后一种方法,有一个内置的收集器调用summarizingInt它返回a IntSummaryStatistics,您可以从中获取您需要的所有统计信息。
public static double normalizedMean(Stream<Integer> stream) {
var stats = stream.collect(Collectors.summarizingInt(x -> x));
int max = stats.getMax();
int min = stats.getMin();
double average = stats.getAverage();
return (average - min) / (max - min);
}
我还建议你IntStream改用一个。这样您就可以避免装箱/拆箱,只需执行以下操作:
var stats = stream.summaryStatistics();