В JDK 8 представлены три новых класса : DoubleSummaryStatistics , IntSummaryStatistics и LongSummaryStatistics пакета java.util . Эти классы позволяют быстро и легко вычислить общее количество элементов, минимальное значение элементов, максимальное значение элементов, среднее значение элементов и сумму элементов в коллекции значений типа double, целых или длинных. Документация Javadoc на уровне классов каждого класса начинается с одного и того же предложения, которое кратко излагает это, описывая каждое как «объект состояния для сбора статистики, такой как count, min, max, sum и medium».
Javadoc уровня класса для каждого из этих трех классов также сообщает каждому классу: «Этот класс предназначен для работы (хотя и не требует) с потоками». Наиболее очевидная причина включения этих трех типов классов SummaryStatistics заключается в использовании с потоками , которые также были представлены в JDK 8 .
 Действительно, каждый из трех комментариев класса Javadoc на уровне класса также предоставляет пример использования каждого класса в сочетании с потоками соответствующего типа данных.  Эти примеры демонстрируют вызов соответствующего метода Streams (Supplier, BiConsumer, BiConsumer) ( операция с изменяемым терминальным потоком ) и передача нового экземпляра класса SummaryStatistics (конструктор), принятие и объединение методов (как ссылки на метод ) в этот метод collect в качестве аргументов «поставщик», «аккумулятор» и «объединитель» соответственно. 
  Остальная часть этой статьи демонстрирует использование IntSummaryStatistics , LongSummaryStatistics и DoubleSummaryStatistics .  Некоторые из этих примеров будут ссылаться на карту сезонов телесериала «Секретные материалы » и рейтинг Нильсена для премьеры этого сезона.  Это показано в следующем листинге кода. 
Объявление и инициализация xFilesSeasonPremierRatings
| 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 | /** * Maps the number of each X-Files season to the Nielsen rating * (millions of viewers) for the premiere episode of that season. */privatefinalstaticMap<Integer, Double> xFilesSeasonPremierRatings;static{   finalMap<Integer, Double> temporary = newHashMap<>();   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 к потоку части «значений» карты, и она очень похожа на примеры, представленные в Javadoc для трех классов SummaryStatistics.  Класс DoubleSummaryStatistics класс IntSummaryStatistics и класс LongSummaryStatistics имеют по существу одинаковые поля, методы и API (только различия являются поддерживаемыми типами данных).  Поэтому, хотя этот и многие из примеров этого поста специально используют DoubleSummaryStatistics (поскольку рейтинги Нильсена в X-Files имеют двойные значения), эти принципы применяются к двум другим интегральным типам классов SummaryStatistics. 
Использование DoubleSummaryStatistics с потоком на основе коллекции
| 01 02 03 04 05 06 07 08 09 10 11 12 13 14 | /** * Demonstrate use of DoubleSummaryStatistics collected from a * Collection Stream via use of DoubleSummaryStatistics method * references "new", "accept", and "combine". */privatestaticvoiddemonstrateDoubleSummaryStatisticsOnCollectionStream(){   finalDoubleSummaryStatistics doubleSummaryStatistics =      xFilesSeasonPremierRatings.values().stream().collect(         DoubleSummaryStatistics::new,         DoubleSummaryStatistics::accept,         DoubleSummaryStatistics::combine);   out.println("X-Files Season Premieres: "+ doubleSummaryStatistics);} | 
Результат выполнения вышеприведенной демонстрации показан ниже:
| 1 | X-Files Season Premieres: DoubleSummaryStatistics{count=9, sum=161.020000, min=10.600000, average=17.891111, max=27.340000} | 
  В предыдущем примере класс SummaryStatistics применялся к потоку, основанному непосредственно на коллекции (часть «значения» Map ).  Следующий листинг кода демонстрирует аналогичный пример, но использует IntSummaryStatistics и использует промежуточную операцию отображения потока, чтобы указать, какую функцию вызывать для объектов коллекции для заполнения объекта SummaryStatistics.  В этом случае для коллекции используется объект Set<Movie> возвращаемый методом Java8StreamsMoviesDemo.getMoviesSample() и Java8StreamsMoviesDemo.getMoviesSample() в моем сообщении блога Stream-Powered Collections Functionality в JDK 8 . 
Использование IntSummaryStatistics с картой потока (функция)
| 01 02 03 04 05 06 07 08 09 10 11 12 13 | /** * Demonstrate collecting IntSummaryStatistics via mapping of * certain method calls on objects within a collection and using * lambda expressions (method references in particular). */privatestaticvoiddemonstrateIntSummaryStatisticsWithMethodReference(){   finalSet<Movie> 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);} | 
Когда приведенная выше демонстрация выполняется, ее вывод выглядит так:
| 1 | IntSummaryStatistics on IMDB Top Rated Movies: IntSummaryStatistics{count=5, sum=106, min=1, average=21.200000, max=49} | 
  До сих пор примеры демонстрировали использование классов SummaryStatistics в их наиболее распространенном случае использования (в сочетании с данными из потоков на основе существующих коллекций).  В следующем примере демонстрируется, как можно создать экземпляр DoubleStream с нуля с помощью DoubleStream.Builder, а затем можно вызвать метод summaryStatistics () DoubleStream, чтобы получить экземпляр DoubleSummaryStatistics . 
Получение экземпляра DoubleSummaryStatistics из DoubleStream
| 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 | /** * Uses DoubleStream.builder to build an arbitrary DoubleStream. * * @return DoubleStream constructed with hard-coded doubles using *    a DoubleStream.builder. */privatestaticDoubleStream createSampleOfArbitraryDoubles(){   returnDoubleStream.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(). */privatestaticvoiddemonstrateDoubleSummaryStatisticsOnDoubleStream(){   finalDoubleSummaryStatistics doubleSummaryStatistics =      createSampleOfArbitraryDoubles().summaryStatistics();   out.println("'Arbitrary' Double Statistics: "+ doubleSummaryStatistics);} | 
Только что перечисленный код производит этот вывод:
| 1 | '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 . 
  Для использования классов SummaryStatistics не нужно иметь поток сбора данных или другой экземпляр BaseStream, поскольку они могут быть созданы непосредственно и использованы непосредственно для предопределенных числовых статистических операций.  Следующий листинг кода демонстрирует это путем непосредственного создания экземпляра и последующего DoubleSummaryStatistics экземпляра DoubleSummaryStatistics . 
Непосредственная реализация DoubleSummaryStatistics
| 01 02 03 04 05 06 07 08 09 10 11 12 13 14 | /** * Demonstrate direct instantiation of and population of instance * of DoubleSummaryStatistics instance. */privatestaticvoiddemonstrateDirectAccessToDoubleSummaryStatistics(){   finalDoubleSummaryStatistics doubleSummaryStatistics =      newDoubleSummaryStatistics();   doubleSummaryStatistics.accept(5.0);   doubleSummaryStatistics.accept(10.0);   doubleSummaryStatistics.accept(15.0);   doubleSummaryStatistics.accept(20.0);   out.println("Direct DoubleSummaryStatistics Usage: "+ doubleSummaryStatistics);} | 
Результат выполнения предыдущего листинга кода показан ниже:
| 1 | Direct DoubleSummaryStatistics Usage: DoubleSummaryStatistics{count=4, sum=50.000000, min=5.000000, average=12.500000, max=20.000000} | 
  Как и в предыдущем листинге кода для DoubleSummaryStatistics , следующий листинг LongSummaryStatistics непосредственно создает экземпляр LongSummaryStatistics и заполняет его).  Этот пример также демонстрирует, как классы SummaryStatistics предоставляют отдельные методы для запроса отдельной статистики. 
Непосредственно создание LongSummaryStatistics / Запрос индивидуальной статистики
| 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | /** * Demonstrate use of LongSummaryStatistics with this particular * example directly instantiating and populating an instance of * LongSummaryStatistics that represents hypothetical time * durations measured in milliseconds. */privatestaticvoiddemonstrateLongSummaryStatistics(){   // 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 = newLongSummaryStatistics();   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());} | 
Вывод из этого примера теперь показан:
| 1 2 3 4 5 6 | 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 | 
В большинстве примеров в этой статье я опирался на читаемые реализации toString () классов SummaryStatistics, чтобы продемонстрировать статистику, доступную в каждом классе. Этот последний пример, однако, продемонстрировал, что каждый отдельный тип статистики (количество значений, максимальное значение, минимальное значение, сумма значений и среднее значение) может быть извлечен индивидуально в числовой форме.
Вывод
Независимо от того, предоставляются ли анализируемые данные непосредственно в виде числового потока, предоставляются косвенно через поток коллекции или помещаются вручную в соответствующий экземпляр класса SummaryStatistics, три класса SummaryStatistics могут предоставлять полезные общие статистические вычисления для целых, длинных и двойных чисел.
| Ссылка: | Классы JDK 8 SummaryStatistics от нашего партнера JCG Дастина Маркса в блоге Inspired by Actual Events . |