java - Collectors.averagingInt - 这是一个运行平均值还是将所有以前的数字保留在内存中?
问题描述
在下面的代码中,平均是作为运行平均值工作还是将所有先前的整数保留在内存中并每次重新计算平均值?我想要的是一个运行平均值,因为文件中的整数数量可能非常大(所以我不希望它们都保存在内存中),但另一个开发人员指出第四行实际上可能会尝试将所有整数保存在内存中并每次重新计算平均值。哪一个是正确的?谢谢
return Files.readAllLines(Paths.get(fileName)).stream()
.flatMap(n -> Arrays.stream(n.split(" ")))
.map(Integer::valueOf)
.collect(Collectors.averagingInt(Integer::intValue));
解决方案
平均收集器不需要将其平均的所有数字保存在内存中:它只需要跟踪元素的总和和计数,然后在最后除以得出平均值。
因此,从文件中读取多少内容并不重要:用于计算平均值的空间是恒定的。
Effective Java 3rd Edition,第 214 页有一点,它说您应该只使用某些收集器作为下游收集器 -Collectors.averagingInt
就是这样的收集器。您不需要将这些收集器用作“主要”(如果这是正确的术语)收集器,因为相同的功能可直接在流的 API 上使用。
更正确的方法是使用IntStream
,它有一个average()
方法:
return Files.readAllLines(Paths.get(fileName)).stream()
.flatMap(n -> Arrays.stream(n.split(" ")))
.mapToInt(Integer::parseInt)
.average() // Returns an OptionalDouble
.orElse(0); // averagingInt returns 0 if the stream is empty.
推荐阅读
- python - 仅更新实时 DataFrame 中的数据的正确方法是什么?
- java - Vaadin 无缓冲网格不会关闭
- devops - 如何在 Azure Devops Repo 中上传 excel 文件?
- python - seaborn/matplotlib:在一个图中显示不同的刻度范围
- java - 两个日期之间的 Java HashMap 过滤器
- c - 为什么我的函数 encodeChar 不起作用?
- c# - 当对象中的数据发生变化时触发事件#OpenTK
- asp.net-mvc - 使用 asp core mvc 和 sql 存储过程更新/编辑多对多表
- javascript - 颜色和符号替换代码的问题
- mongodb - 在 React Native 中从我的 API 中删除帖子时,我不断收到 [未处理的承诺拒绝:错误:请求失败,状态码为 404]