如何使用Java 8 lambda顺序计算多个数字的平均值

前端之家收集整理的这篇文章主要介绍了如何使用Java 8 lambda顺序计算多个数字的平均值前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
如果我有集合点,我如何使用 Java 8流在单次迭代中计算x,y的平均值.

以下示例创建两个流&在输入集合上迭代两次,以计算x&年.是他们任何方式计算机平均x,y在单次迭代使用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λ.
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实例组合成一个收集器,将各个值收集到一个元组中.

这比任何其他解决方案更简洁和可重用.你要付出的代价是这个目前的操作是包装类型,而不是原始的double.我想我们必须等到Java 10 and project valhalla for primitive type specialisation in generics.

如果您想自己滚动,而不是创建依赖关系,相关方法如下所示:

static <T,A1,A2,D1,D2> Collector<T,Tuple2<A1,A2>,Tuple2<D1,D2>> collectors(
    Collector<T,D1> collector1,Collector<T,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或类似的东西.

我也在an answer to another Stack Overflow question详细介绍了这种技术.

猜你在找的Java相关文章