1 /*
   2  * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 package java.util;
  26 
  27 import java.util.function.IntConsumer;
  28 import java.util.function.LongConsumer;
  29 
  30 /**
  31  * A state object for collecting statistics such as count, min, max, sum, and
  32  * average.
  33  *
  34  * <p>This class is designed to work with (though does not require)
  35  * {@linkplain java.util.stream streams}. For example, you can compute
  36  * summary statistics on a stream of longs with:
  37  * <pre> {@code
  38  * LongSummaryStatistics stats = longStream.collect(LongSummaryStatistics::new,
  39  *     LongSummaryStatistics::accept,
  40  *     LongSummaryStatistics::combine);
  41  * }</pre>
  42  *
  43  * <p>{@code LongSummaryStatistics} can be used as a
  44  * {@linkplain java.util.stream.Stream#reduce(java.util.function.BinaryOperator) reduction}
  45  * target for a {@linkplain java.util.stream.Stream stream}. For example:
  46  *
  47  * <pre> {@code
  48  * LongSummaryStatistics stats = people.stream()
  49  *     .collect(Collectors.toLongSummaryStatistics(Person::getAge));
  50  *}</pre>
  51  *
  52  * This computes, in a single pass, the count of people, as well as the minimum,
  53  * maximum, sum, and average of their ages in milliseconds.
  54  *
  55  * @implNote This implementation is not thread safe. However, it is safe to use
  56  * {@link java.util.stream.Collectors#toLongSummaryStatistics(java.util.function.ToLongFunction)
  57  * Collectors.toLongStatistics()} on a parallel stream, because the parallel
  58  * implementation of {@link java.util.stream.Stream#collect Stream.collect()}
  59  * provides the necessary partitioning, isolation, and merging of results for
  60  * safe and efficient parallel execution.
  61  *
  62  * <p>This implementation does not check for overflow of the sum.
  63  * @since 1.8
  64  */
  65 public class LongSummaryStatistics implements LongConsumer, IntConsumer {
  66     private long count;
  67     private long sum;
  68     private long min = Long.MAX_VALUE;
  69     private long max = Long.MIN_VALUE;
  70 
  71     /**
  72      * Records a new {@code int} value into the summary information.
  73      *
  74      * @param value the input value
  75      */
  76     @Override
  77     public void accept(int value) {
  78         accept((long) value);
  79     }
  80 
  81     /**
  82      * Records a new {@code long} value into the summary information.
  83      *
  84      * @param value the input value
  85      */
  86     @Override
  87     public void accept(long value) {
  88         ++count;
  89         sum += value;
  90         min = Math.min(min, value);
  91         max = Math.max(max, value);
  92     }
  93 
  94     /**
  95      * Combines the state of another {@code LongSummaryStatistics} into this
  96      * one.
  97      *
  98      * @param other Another {@code LongSummaryStatistics}
  99      * @throws NullPointerException if {@code other} is null
 100      */
 101     public void combine(LongSummaryStatistics other) {
 102         count += other.count;
 103         sum += other.sum;
 104         min = Math.min(min, other.min);
 105         max = Math.max(max, other.max);
 106     }
 107 
 108     /**
 109      * Returns the count of values recorded.
 110      *
 111      * @return the count of values
 112      */
 113     public long getCount() {
 114         return count;
 115     }
 116 
 117     /**
 118      * Returns the sum of values recorded, or zero if no values have been
 119      * recorded.
 120      *
 121      * @return The sum of values, or zero if none
 122      */
 123     public long getSum() {
 124         return sum;
 125     }
 126 
 127     /**
 128      * Returns the minimal value recorded, or {@code Long.MAX_VALUE} if no
 129      * values have been recorded.
 130      *
 131      * @return The minimal value, or {@code Long.MAX_VALUE} if none
 132      */
 133     public long getMin() {
 134         return min;
 135     }
 136 
 137     /**
 138      * Returns the maximal value recorded, or {@code Long.MIN_VALUE} if no
 139      * values have been recorded
 140      *
 141      * @return The maximal value, or {@code Long.MIN_VALUE} if none
 142      */
 143     public long getMax() {
 144         return max;
 145     }
 146 
 147     /**
 148      * Returns the average of values recorded, or zero if no values have been
 149      * recorded.
 150      *
 151      * @return The average of values, or zero if none
 152      */
 153     public double getAverage() {
 154         return count > 0 ? (double) sum / count : 0.0d;
 155     }
 156 
 157     @Override
 158     /**
 159      * {@inheritDoc}
 160      *
 161      * Returns a non-empty string representation of this object suitable for
 162      * debugging. The exact presentation format is unspecified and may vary
 163      * between implementations and versions.
 164      */
 165     public String toString() {
 166         return String.format(
 167             "%s{count=%d, sum=%d, min=%d, average=%d, max=%d}",
 168             this.getClass().getSimpleName(),
 169             getCount(),
 170             getSum(),
 171             getMin(),
 172             getAverage(),
 173             getMax()).toString();
 174     }
 175 }