Java 8流(Stream):同时求平均值和计数

3
我有一个DoubleStream,它是从一个非常耗时的函数计算出来的,我想同时计算它的元素的平均值和数量。
问题是我不想因为这个耗时的值计算两次DoubleStream。我想从一个lambda表达式中获得平均值和数量的值。
我已经尝试了使用collect和map等所有方法,但都没有成功。
    final long count = products.stream()
            .mapToDouble(this::timeConsumingCalculateRating)
            .filter(rating -> rating > 0.0D)
            .count();

    final double averageRating = products.stream()
            .mapToDouble(this::timeConsumingCalculateRating)
            .filter(rating -> rating > 0.0D)
            .average()
            .orElse(0.0D);

任何帮助都非常感激。
2个回答

13

使用summaryStatistics()方法:

DoubleSummaryStatistics stats = products.stream()
            .mapToDouble(this::timeConsumingCalculateRating)
            .filter(rating -> rating > 0.0D)
            .summaryStatistics();
long count = stats.getCount();
double averageRating = stats.getAverage();

5

对于计数和平均值,summaryStatistics已经足够了。但是如果你有其他的终端操作,并且你还需要计算元素个数,你可以使用peekAtomicLongAtomicInteger

AtomicLong counter = new AtomicLong();
double average = products.stream()
        .mapToDouble(this::timeConsumingCalculateRating)
        .filter(rating -> rating > 0.0D)
        .peek(d -> counter.incrementAndGet())
        .average().orElse(0.0);
long count = counter.get();

那个 peek 应该被称为 tee ;) - WestCoastProjects

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接