Skip to content

Commit 1ee8cc9

Browse files
cpovirkGoogle Java Core Libraries
authored andcommitted
DO NOT MERGE
Demo of Guava changes for openjdk/jdk#23461. This change pre-sizes collectors for which the size of the output collection must match the size of the input stream. It omits cases like `ImmutableSet` (which deduplicates), but it includes cases `ImmutableList` (obviously) and `ImmutableMap`/`ImmutableBiMap` (which rejects duplicate keys). RELNOTES=`collect`: Changed `toImmutableList`, `toImmutableMap`, and `toImmutableBiMap` to internally pre-size their collections when possible. PiperOrigin-RevId: 725756865
1 parent d650068 commit 1ee8cc9

File tree

2 files changed

+128
-6
lines changed

2 files changed

+128
-6
lines changed

android/guava/src/com/google/common/collect/CollectCollectors.java

Lines changed: 64 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,24 +17,31 @@
1717
package com.google.common.collect;
1818

1919
import static com.google.common.base.Preconditions.checkNotNull;
20+
import static com.google.common.collect.Sets.immutableEnumSet;
21+
import static java.util.Arrays.asList;
2022
import static java.util.Collections.singletonMap;
2123
import static java.util.stream.Collectors.collectingAndThen;
2224
import static java.util.stream.Collectors.toMap;
2325

2426
import com.google.common.annotations.GwtCompatible;
2527
import com.google.common.annotations.GwtIncompatible;
2628
import com.google.common.base.Preconditions;
29+
import com.google.common.primitives.Ints;
2730
import java.util.Collection;
2831
import java.util.Comparator;
2932
import java.util.EnumMap;
3033
import java.util.EnumSet;
3134
import java.util.LinkedHashMap;
35+
import java.util.Set;
3236
import java.util.TreeMap;
37+
import java.util.function.BiConsumer;
3338
import java.util.function.BinaryOperator;
3439
import java.util.function.Function;
40+
import java.util.function.LongFunction;
3541
import java.util.function.Supplier;
3642
import java.util.function.ToIntFunction;
3743
import java.util.stream.Collector;
44+
import java.util.stream.Collector.Characteristics;
3845
import java.util.stream.Stream;
3946
import org.jspecify.annotations.Nullable;
4047

@@ -43,10 +50,56 @@
4350
@SuppressWarnings("Java7ApiChecker")
4451
@IgnoreJRERequirement // used only from APIs with Java 8 types in them
4552
final class CollectCollectors {
53+
private static <
54+
T extends @Nullable Object, A extends @Nullable Object, R extends @Nullable Object>
55+
Collector<T, A, R> sizedCollector(
56+
Supplier<A> supplier,
57+
LongFunction<A> sizedSupplier,
58+
BiConsumer<A, T> accumulator,
59+
BinaryOperator<A> combiner,
60+
Function<A, R> finisher,
61+
Characteristics... characteristics) {
62+
Set<Characteristics> characteristicsSet = immutableEnumSet(asList(characteristics));
63+
return new Collector<T, A, R>() {
64+
@Override
65+
public Supplier<A> supplier() {
66+
return supplier;
67+
}
68+
69+
@SuppressWarnings("MissingOverride") // only under some future version of Java?
70+
public LongFunction<A> sizedSupplier() {
71+
return sizedSupplier;
72+
}
73+
74+
@Override
75+
public BiConsumer<A, T> accumulator() {
76+
return accumulator;
77+
}
78+
79+
@Override
80+
public BinaryOperator<A> combiner() {
81+
return combiner;
82+
}
83+
84+
@Override
85+
public Function<A, R> finisher() {
86+
return finisher;
87+
}
88+
89+
@Override
90+
public Set<Characteristics> characteristics() {
91+
return characteristicsSet;
92+
}
93+
};
94+
}
4695

4796
private static final Collector<Object, ?, ImmutableList<Object>> TO_IMMUTABLE_LIST =
48-
Collector.of(
97+
sizedCollector(
4998
ImmutableList::builder,
99+
size ->
100+
size == -1
101+
? ImmutableList.builder()
102+
: ImmutableList.builderWithExpectedSize(Ints.checkedCast(size)),
50103
ImmutableList.Builder::add,
51104
ImmutableList.Builder::combine,
52105
ImmutableList.Builder::build);
@@ -191,8 +244,12 @@ ImmutableSet<E> toImmutableSet() {
191244
Function<? super T, ? extends V> valueFunction) {
192245
checkNotNull(keyFunction);
193246
checkNotNull(valueFunction);
194-
return Collector.of(
247+
return sizedCollector(
195248
ImmutableMap.Builder<K, V>::new,
249+
size ->
250+
size == -1
251+
? new ImmutableMap.Builder<K, V>()
252+
: new ImmutableMap.Builder<K, V>(Ints.checkedCast(size)),
196253
(builder, input) -> builder.put(keyFunction.apply(input), valueFunction.apply(input)),
197254
ImmutableMap.Builder::combine,
198255
ImmutableMap.Builder::buildOrThrow);
@@ -249,8 +306,12 @@ ImmutableSet<E> toImmutableSet() {
249306
Function<? super T, ? extends V> valueFunction) {
250307
checkNotNull(keyFunction);
251308
checkNotNull(valueFunction);
252-
return Collector.of(
309+
return sizedCollector(
253310
ImmutableBiMap.Builder<K, V>::new,
311+
size ->
312+
size == -1
313+
? new ImmutableBiMap.Builder<K, V>()
314+
: new ImmutableBiMap.Builder<K, V>(Ints.checkedCast(size)),
254315
(builder, input) -> builder.put(keyFunction.apply(input), valueFunction.apply(input)),
255316
ImmutableBiMap.Builder::combine,
256317
ImmutableBiMap.Builder::buildOrThrow,

guava/src/com/google/common/collect/CollectCollectors.java

Lines changed: 64 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,34 +17,87 @@
1717
package com.google.common.collect;
1818

1919
import static com.google.common.base.Preconditions.checkNotNull;
20+
import static com.google.common.collect.Sets.immutableEnumSet;
21+
import static java.util.Arrays.asList;
2022
import static java.util.Collections.singletonMap;
2123
import static java.util.stream.Collectors.collectingAndThen;
2224
import static java.util.stream.Collectors.toMap;
2325

2426
import com.google.common.annotations.GwtCompatible;
2527
import com.google.common.annotations.GwtIncompatible;
2628
import com.google.common.base.Preconditions;
29+
import com.google.common.primitives.Ints;
2730
import java.util.Collection;
2831
import java.util.Comparator;
2932
import java.util.EnumMap;
3033
import java.util.EnumSet;
3134
import java.util.LinkedHashMap;
35+
import java.util.Set;
3236
import java.util.TreeMap;
37+
import java.util.function.BiConsumer;
3338
import java.util.function.BinaryOperator;
3439
import java.util.function.Function;
40+
import java.util.function.LongFunction;
3541
import java.util.function.Supplier;
3642
import java.util.function.ToIntFunction;
3743
import java.util.stream.Collector;
44+
import java.util.stream.Collector.Characteristics;
3845
import java.util.stream.Stream;
3946
import org.jspecify.annotations.Nullable;
4047

4148
/** Collectors utilities for {@code common.collect} internals. */
4249
@GwtCompatible
4350
final class CollectCollectors {
51+
private static <
52+
T extends @Nullable Object, A extends @Nullable Object, R extends @Nullable Object>
53+
Collector<T, A, R> sizedCollector(
54+
Supplier<A> supplier,
55+
LongFunction<A> sizedSupplier,
56+
BiConsumer<A, T> accumulator,
57+
BinaryOperator<A> combiner,
58+
Function<A, R> finisher,
59+
Characteristics... characteristics) {
60+
Set<Characteristics> characteristicsSet = immutableEnumSet(asList(characteristics));
61+
return new Collector<T, A, R>() {
62+
@Override
63+
public Supplier<A> supplier() {
64+
return supplier;
65+
}
66+
67+
@SuppressWarnings("MissingOverride") // only under some future version of Java?
68+
public LongFunction<A> sizedSupplier() {
69+
return sizedSupplier;
70+
}
71+
72+
@Override
73+
public BiConsumer<A, T> accumulator() {
74+
return accumulator;
75+
}
76+
77+
@Override
78+
public BinaryOperator<A> combiner() {
79+
return combiner;
80+
}
81+
82+
@Override
83+
public Function<A, R> finisher() {
84+
return finisher;
85+
}
86+
87+
@Override
88+
public Set<Characteristics> characteristics() {
89+
return characteristicsSet;
90+
}
91+
};
92+
}
4493

4594
private static final Collector<Object, ?, ImmutableList<Object>> TO_IMMUTABLE_LIST =
46-
Collector.of(
95+
sizedCollector(
4796
ImmutableList::builder,
97+
size ->
98+
size == -1
99+
? ImmutableList.builder()
100+
: ImmutableList.builderWithExpectedSize(Ints.checkedCast(size)),
48101
ImmutableList.Builder::add,
49102
ImmutableList.Builder::combine,
50103
ImmutableList.Builder::build);
@@ -188,8 +241,12 @@ ImmutableSet<E> toImmutableSet() {
188241
Function<? super T, ? extends V> valueFunction) {
189242
checkNotNull(keyFunction);
190243
checkNotNull(valueFunction);
191-
return Collector.of(
244+
return sizedCollector(
192245
ImmutableMap.Builder<K, V>::new,
246+
size ->
247+
size == -1
248+
? new ImmutableMap.Builder<K, V>()
249+
: new ImmutableMap.Builder<K, V>(Ints.checkedCast(size)),
193250
(builder, input) -> builder.put(keyFunction.apply(input), valueFunction.apply(input)),
194251
ImmutableMap.Builder::combine,
195252
ImmutableMap.Builder::buildOrThrow);
@@ -246,8 +303,12 @@ ImmutableSet<E> toImmutableSet() {
246303
Function<? super T, ? extends V> valueFunction) {
247304
checkNotNull(keyFunction);
248305
checkNotNull(valueFunction);
249-
return Collector.of(
306+
return sizedCollector(
250307
ImmutableBiMap.Builder<K, V>::new,
308+
size ->
309+
size == -1
310+
? new ImmutableBiMap.Builder<K, V>()
311+
: new ImmutableBiMap.Builder<K, V>(Ints.checkedCast(size)),
251312
(builder, input) -> builder.put(keyFunction.apply(input), valueFunction.apply(input)),
252313
ImmutableBiMap.Builder::combine,
253314
ImmutableBiMap.Builder::buildOrThrow,

0 commit comments

Comments
 (0)