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 */
25package java.util;
26
27import java.util.function.IntConsumer;
28
29/**
30 * A state object for collecting statistics such as count, min, max, sum, and
31 * average.
32 *
33 * <p>This class is designed to work with (though does not require)
34 * {@linkplain java.util.stream streams}. For example, you can compute
35 * summary statistics on a stream of ints with:
36 * <pre> {@code
37 * IntSummaryStatistics stats = intStream.collect(IntSummaryStatistics::new,
38 *                                                IntSummaryStatistics::accept,
39 *                                                IntSummaryStatistics::combine);
40 * }</pre>
41 *
42 * <p>{@code IntSummaryStatistics} can be used as a
43 * {@linkplain java.util.stream.Stream#collect(Collector) reduction}
44 * target for a {@linkplain java.util.stream.Stream stream}. For example:
45 *
46 * <pre> {@code
47 * IntSummaryStatistics stats = people.stream()
48 *                                    .collect(Collectors.summarizingInt(Person::getDependents));
49 *}</pre>
50 *
51 * This computes, in a single pass, the count of people, as well as the minimum,
52 * maximum, sum, and average of their number of dependents.
53 *
54 * @implNote This implementation is not thread safe. However, it is safe to use
55 * {@link java.util.stream.Collectors#summarizingInt(java.util.function.ToIntFunction)
56 * Collectors.toIntStatistics()} on a parallel stream, because the parallel
57 * implementation of {@link java.util.stream.Stream#collect Stream.collect()}
58 * provides the necessary partitioning, isolation, and merging of results for
59 * safe and efficient parallel execution.
60 *
61 * <p>This implementation does not check for overflow of the sum.
62 * @since 1.8
63 */
64public class IntSummaryStatistics implements IntConsumer {
65    private long count;
66    private long sum;
67    private int min = Integer.MAX_VALUE;
68    private int max = Integer.MIN_VALUE;
69
70    /**
71     * Construct an empty instance with zero count, zero sum,
72     * {@code Integer.MAX_VALUE} min, {@code Integer.MIN_VALUE} max and zero
73     * average.
74     */
75    public IntSummaryStatistics() { }
76
77    /**
78     * Records a new value into the summary information
79     *
80     * @param value the input value
81     */
82    @Override
83    public void accept(int value) {
84        ++count;
85        sum += value;
86        min = Math.min(min, value);
87        max = Math.max(max, value);
88    }
89
90    /**
91     * Combines the state of another {@code IntSummaryStatistics} into this one.
92     *
93     * @param other another {@code IntSummaryStatistics}
94     * @throws NullPointerException if {@code other} is null
95     */
96    public void combine(IntSummaryStatistics other) {
97        count += other.count;
98        sum += other.sum;
99        min = Math.min(min, other.min);
100        max = Math.max(max, other.max);
101    }
102
103    /**
104     * Returns the count of values recorded.
105     *
106     * @return the count of values
107     */
108    public final long getCount() {
109        return count;
110    }
111
112    /**
113     * Returns the sum of values recorded, or zero if no values have been
114     * recorded.
115     *
116     * @return the sum of values, or zero if none
117     */
118    public final long getSum() {
119        return sum;
120    }
121
122    /**
123     * Returns the minimum value recorded, or {@code Integer.MAX_VALUE} if no
124     * values have been recorded.
125     *
126     * @return the minimum value, or {@code Integer.MAX_VALUE} if none
127     */
128    public final int getMin() {
129        return min;
130    }
131
132    /**
133     * Returns the maximum value recorded, or {@code Integer.MIN_VALUE} if no
134     * values have been recorded.
135     *
136     * @return the maximum value, or {@code Integer.MIN_VALUE} if none
137     */
138    public final int getMax() {
139        return max;
140    }
141
142    /**
143     * Returns the arithmetic mean of values recorded, or zero if no values have been
144     * recorded.
145     *
146     * @return the arithmetic mean of values, or zero if none
147     */
148    public final double getAverage() {
149        return getCount() > 0 ? (double) getSum() / getCount() : 0.0d;
150    }
151
152    @Override
153    /**
154     * {@inheritDoc}
155     *
156     * Returns a non-empty string representation of this object suitable for
157     * debugging. The exact presentation format is unspecified and may vary
158     * between implementations and versions.
159     */
160    public String toString() {
161        return String.format(
162            "%s{count=%d, sum=%d, min=%d, average=%f, max=%d}",
163            this.getClass().getSimpleName(),
164            getCount(),
165            getSum(),
166            getMin(),
167            getAverage(),
168            getMax());
169    }
170}
171