diff --git a/jdk/src/share/classes/java/util/DoubleSummaryStatistics.java b/jdk/src/share/classes/java/util/DoubleSummaryStatistics.java index fb79c56660b..63c887e23ce 100644 --- a/jdk/src/share/classes/java/util/DoubleSummaryStatistics.java +++ b/jdk/src/share/classes/java/util/DoubleSummaryStatistics.java @@ -25,6 +25,7 @@ package java.util; import java.util.function.DoubleConsumer; +import java.util.stream.Collector; /** * A state object for collecting statistics such as count, min, max, sum, and @@ -35,24 +36,24 @@ import java.util.function.DoubleConsumer; * summary statistics on a stream of doubles with: *
{@code
* DoubleSummaryStatistics stats = doubleStream.collect(DoubleSummaryStatistics::new,
- * DoubleSummaryStatistics::accept,
- * DoubleSummaryStatistics::combine);
+ * DoubleSummaryStatistics::accept,
+ * DoubleSummaryStatistics::combine);
* }
*
* {@code DoubleSummaryStatistics} can be used as a - * {@linkplain java.util.stream.Stream#reduce(java.util.function.BinaryOperator) reduction} + * {@linkplain java.util.stream.Stream#collect(Collector) reduction} * target for a {@linkplain java.util.stream.Stream stream}. For example: * *
{@code
* DoubleSummaryStatistics stats = people.stream()
- * .collect(Collectors.toDoubleSummaryStatistics(Person::getWeight));
+ * .collect(Collectors.summarizingDouble(Person::getWeight));
*}
*
* This computes, in a single pass, the count of people, as well as the minimum,
* maximum, sum, and average of their weights.
*
* @implNote This implementation is not thread safe. However, it is safe to use
- * {@link java.util.stream.Collectors#toDoubleSummaryStatistics(java.util.function.ToDoubleFunction)
+ * {@link java.util.stream.Collectors#summarizingDouble(java.util.function.ToDoubleFunction)
* Collectors.toDoubleStatistics()} on a parallel stream, because the parallel
* implementation of {@link java.util.stream.Stream#collect Stream.collect()}
* provides the necessary partitioning, isolation, and merging of results for
@@ -152,7 +153,7 @@ public class DoubleSummaryStatistics implements DoubleConsumer {
}
/**
- * Returns the average of values recorded, or zero if no values have been
+ * Returns the arithmetic mean of values recorded, or zero if no values have been
* recorded. The average returned can vary depending upon the order in
* which values are recorded. This is due to accumulated rounding error in
* addition of values of differing magnitudes. Values sorted by increasing
@@ -160,7 +161,7 @@ public class DoubleSummaryStatistics implements DoubleConsumer {
* value is a {@code NaN} or the sum is at any point a {@code NaN} then the
* average will be {@code NaN}.
*
- * @return the average of values, or zero if none
+ * @return the arithmetic mean of values, or zero if none
*/
public final double getAverage() {
return getCount() > 0 ? getSum() / getCount() : 0.0d;
diff --git a/jdk/src/share/classes/java/util/IntSummaryStatistics.java b/jdk/src/share/classes/java/util/IntSummaryStatistics.java
index fcca3296f85..f93436e7017 100644
--- a/jdk/src/share/classes/java/util/IntSummaryStatistics.java
+++ b/jdk/src/share/classes/java/util/IntSummaryStatistics.java
@@ -25,6 +25,7 @@
package java.util;
import java.util.function.IntConsumer;
+import java.util.stream.Collector;
/**
* A state object for collecting statistics such as count, min, max, sum, and
@@ -35,24 +36,24 @@ import java.util.function.IntConsumer;
* summary statistics on a stream of ints with:
* {@code
* IntSummaryStatistics stats = intStream.collect(IntSummaryStatistics::new,
- * IntSummaryStatistics::accept,
- * IntSummaryStatistics::combine);
+ * IntSummaryStatistics::accept,
+ * IntSummaryStatistics::combine);
* }
*
* {@code IntSummaryStatistics} can be used as a - * {@linkplain java.util.stream.Stream#reduce(java.util.function.BinaryOperator) reduction} + * {@linkplain java.util.stream.Stream#collect(Collector) reduction} * target for a {@linkplain java.util.stream.Stream stream}. For example: * *
{@code
* IntSummaryStatistics stats = people.stream()
- * .collect(Collectors.toIntSummaryStatistics(Person::getDependents));
+ * .collect(Collectors.summarizingInt(Person::getDependents));
*}
*
* This computes, in a single pass, the count of people, as well as the minimum,
* maximum, sum, and average of their number of dependents.
*
* @implNote This implementation is not thread safe. However, it is safe to use
- * {@link java.util.stream.Collectors#toIntSummaryStatistics(java.util.function.ToIntFunction)
+ * {@link java.util.stream.Collectors#summarizingInt(java.util.function.ToIntFunction)
* Collectors.toIntStatistics()} on a parallel stream, because the parallel
* implementation of {@link java.util.stream.Stream#collect Stream.collect()}
* provides the necessary partitioning, isolation, and merging of results for
@@ -140,10 +141,10 @@ public class IntSummaryStatistics implements IntConsumer {
}
/**
- * Returns the average of values recorded, or zero if no values have been
+ * Returns the arithmetic mean of values recorded, or zero if no values have been
* recorded.
*
- * @return the average of values, or zero if none
+ * @return the arithmetic mean of values, or zero if none
*/
public final double getAverage() {
return getCount() > 0 ? (double) getSum() / getCount() : 0.0d;
diff --git a/jdk/src/share/classes/java/util/LongSummaryStatistics.java b/jdk/src/share/classes/java/util/LongSummaryStatistics.java
index 0e2da71f8bc..085aa298075 100644
--- a/jdk/src/share/classes/java/util/LongSummaryStatistics.java
+++ b/jdk/src/share/classes/java/util/LongSummaryStatistics.java
@@ -26,6 +26,7 @@ package java.util;
import java.util.function.IntConsumer;
import java.util.function.LongConsumer;
+import java.util.stream.Collector;
/**
* A state object for collecting statistics such as count, min, max, sum, and
@@ -36,24 +37,24 @@ import java.util.function.LongConsumer;
* summary statistics on a stream of longs with:
* {@code
* LongSummaryStatistics stats = longStream.collect(LongSummaryStatistics::new,
- * LongSummaryStatistics::accept,
- * LongSummaryStatistics::combine);
+ * LongSummaryStatistics::accept,
+ * LongSummaryStatistics::combine);
* }
*
* {@code LongSummaryStatistics} can be used as a - * {@linkplain java.util.stream.Stream#reduce(java.util.function.BinaryOperator) reduction} + * {@linkplain java.util.stream.Stream#collect(Collector)} reduction} * target for a {@linkplain java.util.stream.Stream stream}. For example: * *
{@code
* LongSummaryStatistics stats = people.stream()
- * .collect(Collectors.toLongSummaryStatistics(Person::getAge));
+ * .collect(Collectors.summarizingLong(Person::getAge));
*}
*
* This computes, in a single pass, the count of people, as well as the minimum,
- * maximum, sum, and average of their ages in milliseconds.
+ * maximum, sum, and average of their ages.
*
* @implNote This implementation is not thread safe. However, it is safe to use
- * {@link java.util.stream.Collectors#toLongSummaryStatistics(java.util.function.ToLongFunction)
+ * {@link java.util.stream.Collectors#summarizingLong(java.util.function.ToLongFunction)
* Collectors.toLongStatistics()} on a parallel stream, because the parallel
* implementation of {@link java.util.stream.Stream#collect Stream.collect()}
* provides the necessary partitioning, isolation, and merging of results for
@@ -152,10 +153,10 @@ public class LongSummaryStatistics implements LongConsumer, IntConsumer {
}
/**
- * Returns the average of values recorded, or zero if no values have been
+ * Returns the arithmetic mean of values recorded, or zero if no values have been
* recorded.
*
- * @return The average of values, or zero if none
+ * @return The arithmetic mean of values, or zero if none
*/
public final double getAverage() {
return getCount() > 0 ? (double) getSum() / getCount() : 0.0d;
diff --git a/jdk/src/share/classes/java/util/StringJoiner.java b/jdk/src/share/classes/java/util/StringJoiner.java
index 66d49b64f0a..d4050a4afd5 100644
--- a/jdk/src/share/classes/java/util/StringJoiner.java
+++ b/jdk/src/share/classes/java/util/StringJoiner.java
@@ -49,16 +49,17 @@ package java.util;
* * A {@code StringJoiner} may be employed to create formatted output from a * {@link java.util.stream.Stream} using - * {@link java.util.stream.Collectors#toStringJoiner}. For example: + * {@link java.util.stream.Collectors#joining(CharSequence)}. For example: * *
{@code
* List numbers = Arrays.asList(1, 2, 3, 4);
* String commaSeparatedNumbers = numbers.stream()
* .map(i -> i.toString())
- * .collect(Collectors.toStringJoiner(", ")).toString();
+ * .collect(Collectors.joining(", "));
* }
*
- * @see java.util.stream.Collectors#toStringJoiner
+ * @see java.util.stream.Collectors#joining(CharSequence)
+ * @see java.util.stream.Collectors#joining(CharSequence, CharSequence, CharSequence)
* @since 1.8
*/
public final class StringJoiner {
diff --git a/jdk/src/share/classes/java/util/stream/Collector.java b/jdk/src/share/classes/java/util/stream/Collector.java
index 71bb2276f7b..49629176032 100644
--- a/jdk/src/share/classes/java/util/stream/Collector.java
+++ b/jdk/src/share/classes/java/util/stream/Collector.java
@@ -25,40 +25,45 @@
package java.util.stream;
import java.util.Collections;
+import java.util.EnumSet;
import java.util.Set;
-import java.util.function.BiFunction;
+import java.util.function.BiConsumer;
import java.util.function.BinaryOperator;
+import java.util.function.Function;
import java.util.function.Supplier;
/**
* A reduction operation that
- * supports folding input elements into a cumulative result. The result may be
- * a value or may be a mutable result container. Examples of operations
- * accumulating results into a mutable result container include: accumulating
- * input elements into a {@code Collection}; concatenating strings into a
- * {@code StringBuilder}; computing summary information about elements such as
- * sum, min, max, or average; computing "pivot table" summaries such as "maximum
- * valued transaction by seller", etc. Reduction operations can be performed
- * either sequentially or in parallel.
+ * folds input elements into a mutable result container, optionally transforming
+ * the accumulated result into a final representation after all input elements
+ * have been processed.
+ *
+ * Examples of mutable reduction operations include: + * accumulating elements into a {@code Collection}; concatenating + * strings using a {@code StringBuilder}; computing summary information about + * elements such as sum, min, max, or average; computing "pivot table" summaries + * such as "maximum valued transaction by seller", etc. Reduction operations + * can be performed either sequentially or in parallel. * *
The following are examples of using the predefined {@code Collector} * implementations in {@link Collectors} with the {@code Stream} API to perform * mutable reduction tasks: *
{@code
- * // Accumulate elements into a List
- * List list = stream.collect(Collectors.toList());
+ * // Accumulate names into a List
+ * List list = people.stream().map(Person::getName).collect(Collectors.toList());
*
- * // Accumulate elements into a TreeSet
- * Set list = stream.collect(Collectors.toCollection(TreeSet::new));
+ * // Accumulate names into a TreeSet
+ * Set list = people.stream().map(Person::getName).collect(Collectors.toCollection(TreeSet::new));
*
* // Convert elements to strings and concatenate them, separated by commas
- * String joined = stream.map(Object::toString)
- * .collect(Collectors.toStringJoiner(", "))
- * .toString();
+ * String joined = things.stream()
+ * .map(Object::toString)
+ * .collect(Collectors.joining(", "));
*
* // Find highest-paid employee
* Employee highestPaid = employees.stream()
- * .collect(Collectors.maxBy(Comparators.comparing(Employee::getSalary)));
+ * .collect(Collectors.maxBy(Comparators.comparing(Employee::getSalary)))
+ * .get();
*
* // Group employees by department
* Map> byDept
@@ -66,7 +71,7 @@ import java.util.function.Supplier;
* .collect(Collectors.groupingBy(Employee::getDepartment));
*
* // Find highest-paid employee by department
- * Map highestPaidByDept
+ * Map> highestPaidByDept
* = employees.stream()
* .collect(Collectors.groupingBy(Employee::getDepartment,
* Collectors.maxBy(Comparators.comparing(Employee::getSalary))));
@@ -74,43 +79,42 @@ import java.util.function.Supplier;
* // Partition students into passing and failing
* Map> passingFailing =
* students.stream()
- * .collect(Collectors.partitioningBy(s -> s.getGrade() >= PASS_THRESHOLD);
+ * .collect(Collectors.partitioningBy(s -> s.getGrade() >= PASS_THRESHOLD));
*
* }
*
- * A {@code Collector} is specified by three functions that work together to - * manage a result or result container. They are: creation of an initial - * result, incorporating a new data element into a result, and combining two - * results into one. The last function -- combining two results into one -- is - * used during parallel operations, where subsets of the input are accumulated - * in parallel, and then the subresults merged into a combined result. The - * result may be a mutable container or a value. If the result is mutable, the - * accumulation and combination functions may either mutate their left argument - * and return that (such as adding elements to a collection), or return a new - * result, in which case it should not perform any mutation. + *
A {@code Collector} is specified by four functions that work together to + * accumulate entries into a mutable result container, and optionally perform + * a final transform on the result. They are: creation of a new result container, + * incorporating a new data element into a result container, combining two + * result containers into one, and performing a final transform on the container. + * The combiner function is used during parallel operations, where + * subsets of the input are accumulated into separate result + * containers, and then the subresults merged into a combined result. The + * combiner function may merge one set of subresults into the other and return + * that, or it may return a new object to describe the combined results. * - *
Collectors also have a set of characteristics, including - * {@link Characteristics#CONCURRENT} and - * {@link Characteristics#STRICTLY_MUTATIVE}. These characteristics provide + *
Collectors also have a set of characteristics, such as + * {@link Characteristics#CONCURRENT}. These characteristics provide * hints that can be used by a reduction implementation to provide better * performance. * *
Libraries that implement reduction based on {@code Collector}, such as * {@link Stream#collect(Collector)}, must adhere to the following constraints: *
{@code
- * BiFunction accumulator = collector.accumulator();
- * R result = collector.resultSupplier().get();
+ * R container = collector.supplier().get();
* for (T t : data)
- * result = accumulator.apply(result, t);
- * return result;
+ * collector.accumulator().accept(container, t);
+ * return collector.finisher().apply(container);
* }
*
* However, the library is free to partition the input, perform the reduction
@@ -149,7 +152,7 @@ import java.util.function.Supplier;
* is accumulating elements into a {@code TreeSet}. In this case, the {@code
* resultSupplier()} function is {@code () -> new Treeset If the collector has the {@link Characteristics#STRICTLY_MUTATIVE}
- * characteristic, then the accumulator function must always return
- * its first argument, after possibly mutating its state.
- *
- * @return a function which folds a new value into a cumulative result
+ * @return a function which folds a new value into a mutable result container
*/
- BiFunction If the collector has the {@link Characteristics#STRICTLY_MUTATIVE}
- * characteristic, then the combiner function must always return
- * its first argument, after possibly mutating its state.
+ * return that, or may return a new result object.
*
* @return a function which combines two partial results into a cumulative
* result
*/
- BinaryOperator If the characteristic {@code IDENTITY_TRANSFORM} is
+ * set, this function may be presumed to be an identity transform with an
+ * unchecked cast from {@code A} to {@code R}.
+ *
+ * @return a function which transforms the intermediate result to the final
+ * result
+ */
+ Function finisher();
/**
* Returns a {@code Set} of {@code Collector.Characteristics} indicating
@@ -213,6 +214,62 @@ public interface Collector If a {@code CONCURRENT} collector is not also {@code UNORDERED},
* then it should only be evaluated concurrently if applied to an
@@ -238,12 +294,10 @@ public interface Collector The sum returned can vary depending upon the order in which
+ * values are recorded, due to accumulated rounding error in
+ * addition of values of differing magnitudes. Values sorted by increasing
+ * absolute magnitude tend to yield more accurate results. If any recorded
+ * value is a {@code NaN} or the sum is at any point a {@code NaN} then the
+ * sum will be {@code NaN}.
+ *
+ * @param The average returned can vary depending upon the order in which
+ * values are recorded, due to accumulated rounding error in
+ * addition of values of differing magnitudes. Values sorted by increasing
+ * absolute magnitude tend to yield more accurate results. If any recorded
+ * value is a {@code NaN} or the sum is at any point a {@code NaN} then the
+ * average will be {@code NaN}.
+ *
+ * @param For example, given a stream of {@code Person}, to calculate the longest
* last name of residents in each city:
* The classification function maps elements to some key type {@code K}.
* The collector produces a {@code Map{@code
- * // Accumulate elements into a List
- * List
*
@@ -103,15 +107,19 @@ import java.util.function.ToLongFunction;
*/
public final class Collectors {
- private static final Set, T, List
> combiner = (left, right) -> {
- switch (left.size()) {
- case 0:
- return right;
- case 1:
- List
>) ArrayList::new, List::add,
+ (left, right) -> { left.addAll(right); return left; },
+ CH_ID);
}
/**
@@ -286,44 +243,58 @@ public final class Collectors {
* {@code Set}
*/
public static
{@code
@@ -364,23 +336,27 @@ public final class Collectors {
*
* @param {@code
- * reducing(0L, mapper, Long::sum)
- * }
+ * Returns a {@code Collector} that produces the sum of a integer-valued
+ * function applied to the input elements. If no elements are present,
+ * the result is 0.
*
* @param {@code
* Comparator
- *
- * @implSpec
- * The default implementation is equivalent to:
- * {@code
- * reducing(null, op);
+ * = people.stream().collect(groupingBy(Person::getCity, reducing(BinaryOperator.maxBy(byHeight))));
* }
*
* @param {@code
* Comparator
*
* @param