Skip to content

Commit 37dc5e9

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 37dc5e9

File tree

2 files changed

+134
-6
lines changed

2 files changed

+134
-6
lines changed

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

Lines changed: 67 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,24 +17,30 @@
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;
3235
import java.util.TreeMap;
36+
import java.util.function.BiConsumer;
3337
import java.util.function.BinaryOperator;
3438
import java.util.function.Function;
39+
import java.util.function.LongFunction;
3540
import java.util.function.Supplier;
3641
import java.util.function.ToIntFunction;
3742
import java.util.stream.Collector;
43+
import java.util.stream.Collector.Characteristics;
3844
import java.util.stream.Stream;
3945
import org.jspecify.annotations.Nullable;
4046

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

4799
private static final Collector<Object, ?, ImmutableList<Object>> TO_IMMUTABLE_LIST =
48-
Collector.of(
100+
sizedCollector(
49101
ImmutableList::builder,
102+
size ->
103+
size == -1
104+
? ImmutableList.builder()
105+
: ImmutableList.builderWithExpectedSize(Ints.checkedCast(size)),
50106
ImmutableList.Builder::add,
51107
ImmutableList.Builder::combine,
52108
ImmutableList.Builder::build);
@@ -191,8 +247,12 @@ ImmutableSet<E> toImmutableSet() {
191247
Function<? super T, ? extends V> valueFunction) {
192248
checkNotNull(keyFunction);
193249
checkNotNull(valueFunction);
194-
return Collector.of(
250+
return sizedCollector(
195251
ImmutableMap.Builder<K, V>::new,
252+
size ->
253+
size == -1
254+
? new ImmutableMap.Builder<K, V>()
255+
: new ImmutableMap.Builder<K, V>(Ints.checkedCast(size)),
196256
(builder, input) -> builder.put(keyFunction.apply(input), valueFunction.apply(input)),
197257
ImmutableMap.Builder::combine,
198258
ImmutableMap.Builder::buildOrThrow);
@@ -249,8 +309,12 @@ ImmutableSet<E> toImmutableSet() {
249309
Function<? super T, ? extends V> valueFunction) {
250310
checkNotNull(keyFunction);
251311
checkNotNull(valueFunction);
252-
return Collector.of(
312+
return sizedCollector(
253313
ImmutableBiMap.Builder<K, V>::new,
314+
size ->
315+
size == -1
316+
? new ImmutableBiMap.Builder<K, V>()
317+
: new ImmutableBiMap.Builder<K, V>(Ints.checkedCast(size)),
254318
(builder, input) -> builder.put(keyFunction.apply(input), valueFunction.apply(input)),
255319
ImmutableBiMap.Builder::combine,
256320
ImmutableBiMap.Builder::buildOrThrow,

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

Lines changed: 67 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,34 +17,90 @@
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;
3235
import java.util.TreeMap;
36+
import java.util.function.BiConsumer;
3337
import java.util.function.BinaryOperator;
3438
import java.util.function.Function;
39+
import java.util.function.LongFunction;
3540
import java.util.function.Supplier;
3641
import java.util.function.ToIntFunction;
3742
import java.util.stream.Collector;
43+
import java.util.stream.Collector.Characteristics;
3844
import java.util.stream.Stream;
3945
import org.jspecify.annotations.Nullable;
4046

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

4597
private static final Collector<Object, ?, ImmutableList<Object>> TO_IMMUTABLE_LIST =
46-
Collector.of(
98+
sizedCollector(
4799
ImmutableList::builder,
100+
size ->
101+
size == -1
102+
? ImmutableList.builder()
103+
: ImmutableList.builderWithExpectedSize(Ints.checkedCast(size)),
48104
ImmutableList.Builder::add,
49105
ImmutableList.Builder::combine,
50106
ImmutableList.Builder::build);
@@ -188,8 +244,12 @@ ImmutableSet<E> toImmutableSet() {
188244
Function<? super T, ? extends V> valueFunction) {
189245
checkNotNull(keyFunction);
190246
checkNotNull(valueFunction);
191-
return Collector.of(
247+
return sizedCollector(
192248
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)),
193253
(builder, input) -> builder.put(keyFunction.apply(input), valueFunction.apply(input)),
194254
ImmutableMap.Builder::combine,
195255
ImmutableMap.Builder::buildOrThrow);
@@ -246,8 +306,12 @@ ImmutableSet<E> toImmutableSet() {
246306
Function<? super T, ? extends V> valueFunction) {
247307
checkNotNull(keyFunction);
248308
checkNotNull(valueFunction);
249-
return Collector.of(
309+
return sizedCollector(
250310
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)),
251315
(builder, input) -> builder.put(keyFunction.apply(input), valueFunction.apply(input)),
252316
ImmutableBiMap.Builder::combine,
253317
ImmutableBiMap.Builder::buildOrThrow,

0 commit comments

Comments
 (0)