我被困在如何找到流的归一化均值上。流包含数字,我正在尝试找到归一化的平均值。方程是归一化的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);
}当我这样做的时候,他们说流已经通过管道传输了。
发布于 2021-03-27 13:50:14
您不能多次使用单个流,因此您必须创建流的副本,或者使用单个缩减操作获取所需的所有统计数据(平均值、最大值、最小值)。
对于前一种方法,您需要知道流的源是什么,即每次调用get时都会给出一个新流的某种Supplier<Stream<Integer>>,并多次调用它:
// 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的内置收集器,它返回一个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();发布于 2021-03-27 13:45:07
您应该流到有序集合中,并在一次迭代中获得最大值、最小值和计数等信息(第一个元素、最后一个元素、集合大小),然后可以再次调用.stream().sum()来查找总和。
因此:
import java.util.*;
import java.util.stream.*;
public class Test{
public static void main(String[] args) {
System.out.println(normalizedStream(Stream.of(1, 2, 3, 4, 5)));
}
public static double normalizedStream(Stream < Integer > stream) {
List < Integer > sortedList = stream.sorted().collect(Collectors.toList());
Integer max = sortedList.get(sortedList.size() - 1);
Integer min = sortedList.get(0);
long count = sortedList.size();
Integer sum = sortedList.stream().mapToInt(Integer::intValue).sum();
return (double)((sum / count) - min) / (max - min);
}
}发布于 2021-03-28 18:45:13
从头开始的lambda解决方案,作为在收集器中没有准备好构建的问题的蓝图
public static double normalizedMean(Stream<Integer> ints) {
int[] min = {Integer.MAX_VALUE};
int[] max = {Integer.MIN_VALUE};
long[] count = {1};
return ints.collect(collectingAndThen(reducing((a, b) -> {
min[0] = min[0] == Integer.MAX_VALUE ? min(a, b) : min(min[0], b);
max[0] = max[0] == Integer.MIN_VALUE ? max(a, b) : max(max[0], b);
count[0]++;
return(a + b);
}), m -> (((double)m.get()) / count[0] - min[0]) / (max[0] - min[0])));
}如果normalizedMean()不是static
可以将min、max和count定义为标量类变量
int min; int max; long count;
https://stackoverflow.com/questions/66828296
复制相似问题