< prev index next >
src/java.base/share/classes/java/util/stream/Collectors.java
Print this page
rev 53968 : enable Collector pre-sizing
rev 53969 : added map loadfactor and collector nullchecks
*** 43,62 ****
import java.util.Optional;
import java.util.Set;
import java.util.StringJoiner;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
! import java.util.function.BiConsumer;
! import java.util.function.BiFunction;
! import java.util.function.BinaryOperator;
! import java.util.function.Consumer;
! import java.util.function.Function;
! import java.util.function.Predicate;
! import java.util.function.Supplier;
! import java.util.function.ToDoubleFunction;
! import java.util.function.ToIntFunction;
! import java.util.function.ToLongFunction;
/**
* Implementations of {@link Collector} that implement various useful reduction
* operations, such as accumulating elements into collections, summarizing
* elements according to various criteria, etc.
--- 43,53 ----
import java.util.Optional;
import java.util.Set;
import java.util.StringJoiner;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
! import java.util.function.*;
/**
* Implementations of {@link Collector} that implement various useful reduction
* operations, such as accumulating elements into collections, summarizing
* elements according to various criteria, etc.
*** 191,218 ****
*
* @param <T> the type of elements to be collected
* @param <R> the type of the result
*/
static class CollectorImpl<T, A, R> implements Collector<T, A, R> {
private final Supplier<A> supplier;
private final BiConsumer<A, T> accumulator;
private final BinaryOperator<A> combiner;
private final Function<A, R> finisher;
private final Set<Characteristics> characteristics;
! CollectorImpl(Supplier<A> supplier,
BiConsumer<A, T> accumulator,
BinaryOperator<A> combiner,
Function<A,R> finisher,
Set<Characteristics> characteristics) {
this.supplier = supplier;
this.accumulator = accumulator;
this.combiner = combiner;
this.finisher = finisher;
this.characteristics = characteristics;
}
CollectorImpl(Supplier<A> supplier,
BiConsumer<A, T> accumulator,
BinaryOperator<A> combiner,
Set<Characteristics> characteristics) {
this(supplier, accumulator, combiner, castingIdentity(), characteristics);
--- 182,228 ----
*
* @param <T> the type of elements to be collected
* @param <R> the type of the result
*/
static class CollectorImpl<T, A, R> implements Collector<T, A, R> {
+ private final IntFunction<A> sizedSupplier;
private final Supplier<A> supplier;
private final BiConsumer<A, T> accumulator;
private final BinaryOperator<A> combiner;
private final Function<A, R> finisher;
private final Set<Characteristics> characteristics;
! CollectorImpl(IntFunction<A> sizedSupplier,
! Supplier<A> supplier,
BiConsumer<A, T> accumulator,
BinaryOperator<A> combiner,
Function<A,R> finisher,
Set<Characteristics> characteristics) {
+ this.sizedSupplier = sizedSupplier;
this.supplier = supplier;
this.accumulator = accumulator;
this.combiner = combiner;
this.finisher = finisher;
this.characteristics = characteristics;
}
+ CollectorImpl(IntFunction<A> sizedSupplier,
+ Supplier<A> supplier,
+ BiConsumer<A, T> accumulator,
+ BinaryOperator<A> combiner,
+ Set<Characteristics> characteristics) {
+ this(sizedSupplier, supplier, accumulator, combiner, castingIdentity(), characteristics);
+ }
+
+ CollectorImpl(Supplier<A> supplier,
+ BiConsumer<A, T> accumulator,
+ BinaryOperator<A> combiner,
+ Function<A,R> finisher,
+ Set<Characteristics> characteristics) {
+ this(ignored -> supplier.get(), supplier, accumulator, combiner, finisher, characteristics);
+ }
+
CollectorImpl(Supplier<A> supplier,
BiConsumer<A, T> accumulator,
BinaryOperator<A> combiner,
Set<Characteristics> characteristics) {
this(supplier, accumulator, combiner, castingIdentity(), characteristics);
*** 227,236 ****
--- 237,251 ----
public Supplier<A> supplier() {
return supplier;
}
@Override
+ public IntFunction<A> sizedSupplier() {
+ return sizedSupplier;
+ }
+
+ @Override
public BinaryOperator<A> combiner() {
return combiner;
}
@Override
*** 273,283 ****
* @return a {@code Collector} which collects all the input elements into a
* {@code List}, in encounter order
*/
public static <T>
Collector<T, ?, List<T>> toList() {
! return new CollectorImpl<>((Supplier<List<T>>) ArrayList::new, List::add,
(left, right) -> { left.addAll(right); return left; },
CH_ID);
}
/**
--- 288,300 ----
* @return a {@code Collector} which collects all the input elements into a
* {@code List}, in encounter order
*/
public static <T>
Collector<T, ?, List<T>> toList() {
! return new CollectorImpl<>((IntFunction<List<T>>) ArrayList::new,
! (Supplier<List<T>>) ArrayList::new,
! List::add,
(left, right) -> { left.addAll(right); return left; },
CH_ID);
}
/**
*** 292,302 ****
* @since 10
*/
@SuppressWarnings("unchecked")
public static <T>
Collector<T, ?, List<T>> toUnmodifiableList() {
! return new CollectorImpl<>((Supplier<List<T>>) ArrayList::new, List::add,
(left, right) -> { left.addAll(right); return left; },
list -> (List<T>)List.of(list.toArray()),
CH_NOID);
}
--- 309,321 ----
* @since 10
*/
@SuppressWarnings("unchecked")
public static <T>
Collector<T, ?, List<T>> toUnmodifiableList() {
! return new CollectorImpl<>((IntFunction<List<T>>) ArrayList::new,
! (Supplier<List<T>>) ArrayList::new,
! List::add,
(left, right) -> { left.addAll(right); return left; },
list -> (List<T>)List.of(list.toArray()),
CH_NOID);
}
*** 455,465 ****
*/
public static <T, U, A, R>
Collector<T, ?, R> mapping(Function<? super T, ? extends U> mapper,
Collector<? super U, A, R> downstream) {
BiConsumer<A, ? super U> downstreamAccumulator = downstream.accumulator();
! return new CollectorImpl<>(downstream.supplier(),
(r, t) -> downstreamAccumulator.accept(r, mapper.apply(t)),
downstream.combiner(), downstream.finisher(),
downstream.characteristics());
}
--- 474,484 ----
*/
public static <T, U, A, R>
Collector<T, ?, R> mapping(Function<? super T, ? extends U> mapper,
Collector<? super U, A, R> downstream) {
BiConsumer<A, ? super U> downstreamAccumulator = downstream.accumulator();
! return new CollectorImpl<>(downstream.sizedSupplier(), downstream.supplier(),
(r, t) -> downstreamAccumulator.accept(r, mapper.apply(t)),
downstream.combiner(), downstream.finisher(),
downstream.characteristics());
}
*** 591,601 ****
characteristics = EnumSet.copyOf(characteristics);
characteristics.remove(Collector.Characteristics.IDENTITY_FINISH);
characteristics = Collections.unmodifiableSet(characteristics);
}
}
! return new CollectorImpl<>(downstream.supplier(),
downstream.accumulator(),
downstream.combiner(),
downstream.finisher().andThen(finisher),
characteristics);
}
--- 610,621 ----
characteristics = EnumSet.copyOf(characteristics);
characteristics.remove(Collector.Characteristics.IDENTITY_FINISH);
characteristics = Collections.unmodifiableSet(characteristics);
}
}
! return new CollectorImpl<>(downstream.sizedSupplier(),
! downstream.supplier(),
downstream.accumulator(),
downstream.combiner(),
downstream.finisher().andThen(finisher),
characteristics);
}
*** 1454,1464 ****
* @see #toConcurrentMap(Function, Function)
*/
public static <T, K, U>
Collector<T, ?, Map<K,U>> toMap(Function<? super T, ? extends K> keyMapper,
Function<? super T, ? extends U> valueMapper) {
! return new CollectorImpl<>(HashMap::new,
uniqKeysMapAccumulator(keyMapper, valueMapper),
uniqKeysMapMerger(),
CH_ID);
}
--- 1474,1485 ----
* @see #toConcurrentMap(Function, Function)
*/
public static <T, K, U>
Collector<T, ?, Map<K,U>> toMap(Function<? super T, ? extends K> keyMapper,
Function<? super T, ? extends U> valueMapper) {
! return new CollectorImpl<>(size -> new HashMap<>((int) Math.ceil(size / .75), .75f),
! HashMap::new,
uniqKeysMapAccumulator(keyMapper, valueMapper),
uniqKeysMapMerger(),
CH_ID);
}
*** 1713,1723 ****
* @see #toConcurrentMap(Function, Function, BinaryOperator, Supplier)
*/
public static <T, K, U>
Collector<T, ?, ConcurrentMap<K,U>> toConcurrentMap(Function<? super T, ? extends K> keyMapper,
Function<? super T, ? extends U> valueMapper) {
! return new CollectorImpl<>(ConcurrentHashMap::new,
uniqKeysMapAccumulator(keyMapper, valueMapper),
uniqKeysMapMerger(),
CH_CONCURRENT_ID);
}
--- 1734,1745 ----
* @see #toConcurrentMap(Function, Function, BinaryOperator, Supplier)
*/
public static <T, K, U>
Collector<T, ?, ConcurrentMap<K,U>> toConcurrentMap(Function<? super T, ? extends K> keyMapper,
Function<? super T, ? extends U> valueMapper) {
! return new CollectorImpl<>(size -> new ConcurrentHashMap<>((int) Math.ceil(size / .75), .75f),
! ConcurrentHashMap::new,
uniqKeysMapAccumulator(keyMapper, valueMapper),
uniqKeysMapMerger(),
CH_CONCURRENT_ID);
}
*** 1931,1940 ****
--- 1953,1966 ----
Objects.requireNonNull(downstream2, "downstream2");
Objects.requireNonNull(merger, "merger");
Supplier<A1> c1Supplier = Objects.requireNonNull(downstream1.supplier(), "downstream1 supplier");
Supplier<A2> c2Supplier = Objects.requireNonNull(downstream2.supplier(), "downstream2 supplier");
+ IntFunction<A1> c1SizedSupplier =
+ Objects.requireNonNull(downstream1.sizedSupplier(), "downstream1 sizedSupplier");
+ IntFunction<A2> c2SizedSupplier =
+ Objects.requireNonNull(downstream2.sizedSupplier(), "downstream2 sizedSupplier");
BiConsumer<A1, ? super T> c1Accumulator =
Objects.requireNonNull(downstream1.accumulator(), "downstream1 accumulator");
BiConsumer<A2, ? super T> c2Accumulator =
Objects.requireNonNull(downstream2.accumulator(), "downstream2 accumulator");
BinaryOperator<A1> c1Combiner = Objects.requireNonNull(downstream1.combiner(), "downstream1 combiner");
*** 1954,1965 ****
c.remove(Collector.Characteristics.IDENTITY_FINISH);
characteristics = Collections.unmodifiableSet(c);
}
class PairBox {
! A1 left = c1Supplier.get();
! A2 right = c2Supplier.get();
void add(T t) {
c1Accumulator.accept(left, t);
c2Accumulator.accept(right, t);
}
--- 1980,2001 ----
c.remove(Collector.Characteristics.IDENTITY_FINISH);
characteristics = Collections.unmodifiableSet(c);
}
class PairBox {
! A1 left;
! A2 right;
!
! PairBox(int initialSize) {
! left = c1SizedSupplier.apply(initialSize);
! right = c2SizedSupplier.apply(initialSize);
! }
!
! PairBox() {
! left = c1Supplier.get();
! right = c2Supplier.get();
! }
void add(T t) {
c1Accumulator.accept(left, t);
c2Accumulator.accept(right, t);
}
*** 1975,1985 ****
R2 r2 = c2Finisher.apply(right);
return merger.apply(r1, r2);
}
}
! return new CollectorImpl<>(PairBox::new, PairBox::add, PairBox::combine, PairBox::get, characteristics);
}
/**
* Implementation class used by partitioningBy.
*/
--- 2011,2026 ----
R2 r2 = c2Finisher.apply(right);
return merger.apply(r1, r2);
}
}
! return new CollectorImpl<>(PairBox::new,
! PairBox::new,
! PairBox::add,
! PairBox::combine,
! PairBox::get,
! characteristics);
}
/**
* Implementation class used by partitioningBy.
*/
< prev index next >