How to compute average of multiple numbers in sequence using Java 8 lambda(如何使用 Java 8 lambda 按顺序计算多个数字的平均值)
问题描述
如果我有集合 Point ,如何在单次迭代中使用 Java 8 流计算 x,y 的平均值.
If I have collections Point , how do I compute average of x,y using Java 8 stream on a single iteration.
以下示例创建两个流 &在输入集合上迭代两次以计算 x & 的平均值是的.他们是否有任何方法可以使用 java 8 lambda 在单次迭代中计算平均 x,y:
Following example creates two stream & iterates twice on the input collection to compute the average of x & y. Is their any way to computer average x,y on single iteration using java 8 lambda :
List<Point2D.Float> points =
Arrays.asList(new Point2D.Float(10.0f,11.0f), new Point2D.Float(1.0f,2.9f));
// java 8, iterates twice
double xAvg = points.stream().mapToDouble( p -> p.x).average().getAsDouble();
double yAvg = points.stream().mapToDouble( p -> p.y).average().getAsDouble();
推荐答案
如果您不介意使用额外的库,我们在 jOOλ,最近.
If you don't mind using an additional library, we've added support for tuple collectors to jOOλ, recently.
Tuple2<Double, Double> avg = points.stream().collect(
Tuple.collectors(
Collectors.averagingDouble(p -> p.x),
Collectors.averagingDouble(p -> p.y)
)
);
在上面的代码中,Tuple.collectors()
结合了几个java.util.stream.Collector
实例到单个 Collector
中,将单个值收集到 元组
.
In the above code, Tuple.collectors()
combines several java.util.stream.Collector
instances into a single Collector
that collects individual values into a Tuple
.
这比任何其他解决方案都更加简洁和可重复使用.你要付出的代价是它目前在包装类型上运行,而不是原始的 double
.我想我们必须等到 Java 10 和原始类型的项目 valhalla专攻泛型.
This is much more concise and reusable than any other solution. The price you'll pay is that this currently operates on wrapper types, instead of primitive double
. I guess we'll have to wait until Java 10 and project valhalla for primitive type specialisation in generics.
如果您想自己滚动,而不是创建依赖项,相关方法如下所示:
In case you want to roll your own, instead of creating a dependency, the relevant method looks like this:
static <T, A1, A2, D1, D2> Collector<T, Tuple2<A1, A2>, Tuple2<D1, D2>> collectors(
Collector<T, A1, D1> collector1
, Collector<T, A2, D2> collector2
) {
return Collector.of(
() -> tuple(
collector1.supplier().get()
, collector2.supplier().get()
),
(a, t) -> {
collector1.accumulator().accept(a.v1, t);
collector2.accumulator().accept(a.v2, t);
},
(a1, a2) -> tuple(
collector1.combiner().apply(a1.v1, a2.v1)
, collector2.combiner().apply(a1.v2, a2.v2)
),
a -> tuple(
collector1.finisher().apply(a.v1)
, collector2.finisher().apply(a.v2)
)
);
}
其中 Tuple2
只是两个值的简单包装器.您不妨使用 AbstractMap.SimpleImmutableEntry
或类似的东西.
Where Tuple2
is just a simple wrapper for two values. You might as well use AbstractMap.SimpleImmutableEntry
or something similar.
我还在an answer to another Stack Overflow question中详细介绍了这种技术.
I've also detailed this technique in an answer to another Stack Overflow question.
这篇关于如何使用 Java 8 lambda 按顺序计算多个数字的平均值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:如何使用 Java 8 lambda 按顺序计算多个数字的平均值


- C++ 和 Java 进程之间的共享内存 2022-01-01
- 如何使用WebFilter实现授权头检查 2022-01-01
- Spring Boot连接到使用仲裁器运行的MongoDB副本集 2022-01-01
- Jersey REST 客户端:发布多部分数据 2022-01-01
- value & 是什么意思?0xff 在 Java 中做什么? 2022-01-01
- Safepoint+stats 日志,输出 JDK12 中没有 vmop 操作 2022-01-01
- Eclipse 插件更新错误日志在哪里? 2022-01-01
- 从 finally 块返回时 Java 的奇怪行为 2022-01-01
- 将log4j 1.2配置转换为log4j 2配置 2022-01-01
- Java包名称中单词分隔符的约定是什么? 2022-01-01