Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openjdk-multiarch-jdk8u
Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/share/classes/java/util/DoubleSummaryStatistics.java
38829 views
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.DoubleConsumer;
28
import java.util.stream.Collector;
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 doubles with:
37
* <pre> {@code
38
* DoubleSummaryStatistics stats = doubleStream.collect(DoubleSummaryStatistics::new,
39
* DoubleSummaryStatistics::accept,
40
* DoubleSummaryStatistics::combine);
41
* }</pre>
42
*
43
* <p>{@code DoubleSummaryStatistics} can be used as a
44
* {@linkplain java.util.stream.Stream#collect(Collector) reduction}
45
* target for a {@linkplain java.util.stream.Stream stream}. For example:
46
*
47
* <pre> {@code
48
* DoubleSummaryStatistics stats = people.stream()
49
* .collect(Collectors.summarizingDouble(Person::getWeight));
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 weights.
54
*
55
* @implNote This implementation is not thread safe. However, it is safe to use
56
* {@link java.util.stream.Collectors#summarizingDouble(java.util.function.ToDoubleFunction)
57
* Collectors.toDoubleStatistics()} 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
* @since 1.8
62
*/
63
public class DoubleSummaryStatistics implements DoubleConsumer {
64
private long count;
65
private double sum;
66
private double sumCompensation; // Low order bits of sum
67
private double simpleSum; // Used to compute right sum for non-finite inputs
68
private double min = Double.POSITIVE_INFINITY;
69
private double max = Double.NEGATIVE_INFINITY;
70
71
/**
72
* Construct an empty instance with zero count, zero sum,
73
* {@code Double.POSITIVE_INFINITY} min, {@code Double.NEGATIVE_INFINITY}
74
* max and zero average.
75
*/
76
public DoubleSummaryStatistics() { }
77
78
/**
79
* Records another value into the summary information.
80
*
81
* @param value the input value
82
*/
83
@Override
84
public void accept(double value) {
85
++count;
86
simpleSum += value;
87
sumWithCompensation(value);
88
min = Math.min(min, value);
89
max = Math.max(max, value);
90
}
91
92
/**
93
* Combines the state of another {@code DoubleSummaryStatistics} into this
94
* one.
95
*
96
* @param other another {@code DoubleSummaryStatistics}
97
* @throws NullPointerException if {@code other} is null
98
*/
99
public void combine(DoubleSummaryStatistics other) {
100
count += other.count;
101
simpleSum += other.simpleSum;
102
sumWithCompensation(other.sum);
103
sumWithCompensation(other.sumCompensation);
104
min = Math.min(min, other.min);
105
max = Math.max(max, other.max);
106
}
107
108
/**
109
* Incorporate a new double value using Kahan summation /
110
* compensated summation.
111
*/
112
private void sumWithCompensation(double value) {
113
double tmp = value - sumCompensation;
114
double velvel = sum + tmp; // Little wolf of rounding error
115
sumCompensation = (velvel - sum) - tmp;
116
sum = velvel;
117
}
118
119
/**
120
* Return the count of values recorded.
121
*
122
* @return the count of values
123
*/
124
public final long getCount() {
125
return count;
126
}
127
128
/**
129
* Returns the sum of values recorded, or zero if no values have been
130
* recorded.
131
*
132
* If any recorded value is a NaN or the sum is at any point a NaN
133
* then the sum will be NaN.
134
*
135
* <p> The value of a floating-point sum is a function both of the
136
* input values as well as the order of addition operations. The
137
* order of addition operations of this method is intentionally
138
* not defined to allow for implementation flexibility to improve
139
* the speed and accuracy of the computed result.
140
*
141
* In particular, this method may be implemented using compensated
142
* summation or other technique to reduce the error bound in the
143
* numerical sum compared to a simple summation of {@code double}
144
* values.
145
*
146
* @apiNote Values sorted by increasing absolute magnitude tend to yield
147
* more accurate results.
148
*
149
* @return the sum of values, or zero if none
150
*/
151
public final double getSum() {
152
// Better error bounds to add both terms as the final sum
153
double tmp = sum + sumCompensation;
154
if (Double.isNaN(tmp) && Double.isInfinite(simpleSum))
155
// If the compensated sum is spuriously NaN from
156
// accumulating one or more same-signed infinite values,
157
// return the correctly-signed infinity stored in
158
// simpleSum.
159
return simpleSum;
160
else
161
return tmp;
162
}
163
164
/**
165
* Returns the minimum recorded value, {@code Double.NaN} if any recorded
166
* value was NaN or {@code Double.POSITIVE_INFINITY} if no values were
167
* recorded. Unlike the numerical comparison operators, this method
168
* considers negative zero to be strictly smaller than positive zero.
169
*
170
* @return the minimum recorded value, {@code Double.NaN} if any recorded
171
* value was NaN or {@code Double.POSITIVE_INFINITY} if no values were
172
* recorded
173
*/
174
public final double getMin() {
175
return min;
176
}
177
178
/**
179
* Returns the maximum recorded value, {@code Double.NaN} if any recorded
180
* value was NaN or {@code Double.NEGATIVE_INFINITY} if no values were
181
* recorded. Unlike the numerical comparison operators, this method
182
* considers negative zero to be strictly smaller than positive zero.
183
*
184
* @return the maximum recorded value, {@code Double.NaN} if any recorded
185
* value was NaN or {@code Double.NEGATIVE_INFINITY} if no values were
186
* recorded
187
*/
188
public final double getMax() {
189
return max;
190
}
191
192
/**
193
* Returns the arithmetic mean of values recorded, or zero if no
194
* values have been recorded.
195
*
196
* If any recorded value is a NaN or the sum is at any point a NaN
197
* then the average will be code NaN.
198
*
199
* <p>The average returned can vary depending upon the order in
200
* which values are recorded.
201
*
202
* This method may be implemented using compensated summation or
203
* other technique to reduce the error bound in the {@link #getSum
204
* numerical sum} used to compute the average.
205
*
206
* @apiNote Values sorted by increasing absolute magnitude tend to yield
207
* more accurate results.
208
*
209
* @return the arithmetic mean of values, or zero if none
210
*/
211
public final double getAverage() {
212
return getCount() > 0 ? getSum() / getCount() : 0.0d;
213
}
214
215
/**
216
* {@inheritDoc}
217
*
218
* Returns a non-empty string representation of this object suitable for
219
* debugging. The exact presentation format is unspecified and may vary
220
* between implementations and versions.
221
*/
222
@Override
223
public String toString() {
224
return String.format(
225
"%s{count=%d, sum=%f, min=%f, average=%f, max=%f}",
226
this.getClass().getSimpleName(),
227
getCount(),
228
getSum(),
229
getMin(),
230
getAverage(),
231
getMax());
232
}
233
}
234
235