jdk 1.8 jdk8
JDK 8中引入的三个新类是java.util包的DoubleSummaryStatistics , IntSummaryStatistics和LongSummaryStatistics 。 这些类使计算元素总数,元素的最小值,元素的最大值,元素的平均值以及双精度,整数或long的集合中的元素总和变得轻松快捷。 每个类的类级别Javadoc文档都以相同的单句开头,简洁地表达了这一点,并将每个句子描述为“一个用于收集统计信息(例如,计数,最小值,最大值,总和和平均值)的状态对象”。
这三个类中的每个类的类级Javadoc都声明了每个类的状态,“该类旨在用于(尽管不需要)流。” 包含这三种类型的SummaryStatistics类的最明显的原因是要与JDK 8一起引入的流一起使用。
实际上,三个类的类级别Javadoc注释中的每个注释也提供了将每个类与相应数据类型的流结合使用的示例。 这些示例演示了如何调用各个Stream的collect(Supplier,BiConsumer,BiConsumer)方法( 可变归约 终端流操作 ),并将每个SummaryStatistics类的新实例 (构造函数)传递给accept方法, 并将方法(作为方法引用 )传递给此collect
方法作为其“供应商”,“累加器”和“合并器”参数。
本文的其余部分将演示IntSummaryStatistics
, LongSummaryStatistics
和DoubleSummaryStatistics
。 这些示例中的几个示例将参考《 X档案》电视连续剧的季节地图,以该季节首映的尼尔森收视率。 这显示在下一个代码清单中。
声明和初始化xFilesSeasonPremierRatings
/**
* Maps the number of each X-Files season to the Nielsen rating
* (millions of viewers) for the premiere episode of that season.
*/
private final static Map xFilesSeasonPremierRatings;
static
{
final Map temporary = new HashMap<>();
temporary.put(1, 12.0);
temporary.put(2, 16.1);
temporary.put(3, 19.94);
temporary.put(4, 21.11);
temporary.put(5, 27.34);
temporary.put(6, 20.24);
temporary.put(7, 17.82);
temporary.put(8, 15.87);
temporary.put(9, 10.6);
xFilesSeasonPremierRatings = Collections.unmodifiableMap(temporary);
}
下一个代码清单使用在上一个代码清单中创建的映射,演示将DoubleSummaryStatistics
应用于DoubleSummaryStatistics
的“值”部分的流,并且与Javadoc中为三个SummaryStatistics类提供的示例非常相似。 DoubleSummaryStatistics
类, IntSummaryStatistics
类和LongSummaryStatistics
类具有基本相同的字段,方法和API(仅差异是受支持的数据类型)。 因此,即使本示例以及本示例中的许多示例都专门使用DoubleSummaryStatistics
(因为X文件的Nielsen等级是DoubleSummaryStatistics
),该原理仍适用于SummaryStatistics类的其他两种不可或缺的类型。
将DoubleSummaryStatistics与基于集合的流一起使用
/**
* Demonstrate use of DoubleSummaryStatistics collected from a
* Collection Stream via use of DoubleSummaryStatistics method
* references "new", "accept", and "combine".
*/
private static void demonstrateDoubleSummaryStatisticsOnCollectionStream()
{
final DoubleSummaryStatistics doubleSummaryStatistics =
xFilesSeasonPremierRatings.values().stream().collect(
DoubleSummaryStatistics::new,
DoubleSummaryStatistics::accept,
DoubleSummaryStatistics::combine);
out.println("X-Files Season Premieres: " + doubleSummaryStatistics);
}
接下来显示运行上述演示的输出:
X-Files Season Premieres: DoubleSummaryStatistics{count=9, sum=161.020000, min=10.600000, average=17.891111, max=27.340000}
上一个示例直接基于集合( Map
的“值”部分)将SummaryStatistics类应用于流。 下一个代码清单演示了一个类似的示例,但是使用IntSummaryStatistics
并使用流的中间映射操作来指定要在集合的对象上调用哪个Function来填充SummaryStatistics对象。 在这种情况下,由Java8StreamsMoviesDemo.getMoviesSample()
方法返回的Set
对集合进行操作,并在我的博客文章JDK 8中的Stream-Powered Collections Functionality中进行了详细说明 。
将IntSummaryStatistics与Stream的地图一起使用(功能)
/**
* Demonstrate collecting IntSummaryStatistics via mapping of
* certain method calls on objects within a collection and using
* lambda expressions (method references in particular).
*/
private static void demonstrateIntSummaryStatisticsWithMethodReference()
{
final Set movies = Java8StreamsMoviesDemo.getMoviesSample();
IntSummaryStatistics intSummaryStatistics =
movies.stream().map(Movie::getImdbTopRating).collect(
IntSummaryStatistics::new, IntSummaryStatistics::accept, IntSummaryStatistics::combine);
out.println("IntSummaryStatistics on IMDB Top Rated Movies: " + intSummaryStatistics);
}
执行上面的演示时,其输出如下所示:
IntSummaryStatistics on IMDB Top Rated Movies: IntSummaryStatistics{count=5, sum=106, min=1, average=21.200000, max=49}
到目前为止,这些示例已在最常用的情况下(与基于现有集合的流中的数据结合使用)使用SummaryStatistics类进行了演示。 下面的例子演示了如何DoubleStream可以从头开始通过利用被实例化DoubleStream.Builder然后DoubleStream的summaryStatistics()方法可以被调用来获得的实例DoubleSummaryStatistics
。
从DoubleStream获取DoubleSummaryStatistics的实例
/**
* Uses DoubleStream.builder to build an arbitrary DoubleStream.
*
* @return DoubleStream constructed with hard-coded doubles using
* a DoubleStream.builder.
*/
private static DoubleStream createSampleOfArbitraryDoubles()
{
return DoubleStream.builder().add(12.4).add(13.6).add(9.7).add(24.5).add(10.2).add(3.0).build();
}
/**
* Demonstrate use of an instance of DoubleSummaryStatistics
* provided by DoubleStream.summaryStatistics().
*/
private static void demonstrateDoubleSummaryStatisticsOnDoubleStream()
{
final DoubleSummaryStatistics doubleSummaryStatistics =
createSampleOfArbitraryDoubles().summaryStatistics();
out.println("'Arbitrary' Double Statistics: " + doubleSummaryStatistics);
}
刚列出的代码将产生以下输出:
'Arbitrary' Double Statistics: DoubleSummaryStatistics{count=6, sum=73.400000, min=3.000000, average=12.233333, max=24.500000}
当然,类似于刚刚所示的例子中, IntStream和IntStream.Builder可以提供的一个实例IntSummaryStatistics
和LongStream和LongStream.Builder可以提供的一个实例LongSummaryStatistics
。
一个人不需要拥有StreamStream或BaseStream的其他实例即可使用SummaryStatistics类,因为它们可以直接实例化并直接用于预定义的数字统计操作。 下一个代码清单通过直接实例化然后填充DoubleSummaryStatistics
的实例来演示这DoubleSummaryStatistics
。
直接实例化DoubleSummaryStatistics
/**
* Demonstrate direct instantiation of and population of instance
* of DoubleSummaryStatistics instance.
*/
private static void demonstrateDirectAccessToDoubleSummaryStatistics()
{
final DoubleSummaryStatistics doubleSummaryStatistics =
new DoubleSummaryStatistics();
doubleSummaryStatistics.accept(5.0);
doubleSummaryStatistics.accept(10.0);
doubleSummaryStatistics.accept(15.0);
doubleSummaryStatistics.accept(20.0);
out.println("Direct DoubleSummaryStatistics Usage: " + doubleSummaryStatistics);
}
接下来显示运行前面的代码清单的输出:
Direct DoubleSummaryStatistics Usage: DoubleSummaryStatistics{count=4, sum=50.000000, min=5.000000, average=12.500000, max=20.000000}
就像前面的DoubleSummaryStatistics
代码清单中DoubleSummaryStatistics
,下一个代码清单直接实例化LongSummaryStatistics
并将其填充)。 此示例还演示了SummaryStatistics类如何提供用于请求单个统计信息的单个方法。
直接实例化LongSummaryStatistics /请求单个统计信息
/**
* Demonstrate use of LongSummaryStatistics with this particular
* example directly instantiating and populating an instance of
* LongSummaryStatistics that represents hypothetical time
* durations measured in milliseconds.
*/
private static void demonstrateLongSummaryStatistics()
{
// This is a series of longs that might represent durations
// of times such as might be calculated by subtracting the
// value returned by System.currentTimeMillis() earlier in
// code from the value returned by System.currentTimeMillis()
// called later in the code.
LongSummaryStatistics timeDurations = new LongSummaryStatistics();
timeDurations.accept(5067054);
timeDurations.accept(7064544);
timeDurations.accept(5454544);
timeDurations.accept(4455667);
timeDurations.accept(9894450);
timeDurations.accept(5555654);
out.println("Test Results Analysis:");
out.println("\tTotal Number of Tests: " + timeDurations.getCount());
out.println("\tAverage Time Duration: " + timeDurations.getAverage());
out.println("\tTotal Test Time: " + timeDurations.getSum());
out.println("\tShortest Test Time: " + timeDurations.getMin());
out.println("\tLongest Test Time: " + timeDurations.getMax());
}
现在显示此示例的输出:
Test Results Analysis:
Total Number of Tests: 6
Average Time Duration: 6248652.166666667
Total Test Time: 37491913
Shortest Test Time: 4455667
Longest Test Time: 9894450
在本文的大多数示例中,我都依赖SummaryStatistics类的可读toString()实现来演示每个类中可用的统计信息。 但是,最后一个示例说明,每种单独的统计类型(值的数量,最大值,最小值,值的总和和平均值)都可以以数字形式分别检索。
结论
无论所分析的数据是直接作为数字流提供,还是通过集合的流间接提供,还是手动放置在适当的SummaryStatistics类实例中,这三个SummaryStatistics类都可以提供有关整数,长整数和双精度数的有用的常用统计计算。
翻译自: https://www.javacodegeeks.com/2015/04/the-jdk-8-summarystatistics-classes.html
jdk 1.8 jdk8