Skip to content

Commit da4e37d

Browse files
committed
Do not create intermediate list in MergedAnnotationCollectors.toAnnotationSet()
Prior to this commit, MergedAnnotationCollectors.toAnnotationSet() created an intermediate ArrayList for storing the results prior to creating a LinkedHashSet in the finishing step. Since the creation of the intermediate list is unnecessary, this commit simplifies the implementation of toAnnotationSet() by using the Collector.of() factory method that does not accept a `finisher` argument. The resulting Collector internally uses a `castingIdentity()` function as the `finisher`. Closes gh-26031
1 parent 010d094 commit da4e37d

File tree

1 file changed

+30
-17
lines changed

1 file changed

+30
-17
lines changed

spring-core/src/main/java/org/springframework/core/annotation/MergedAnnotationCollectors.java

Lines changed: 30 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2019 the original author or authors.
2+
* Copyright 2002-2020 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -18,8 +18,8 @@
1818

1919
import java.lang.annotation.Annotation;
2020
import java.util.ArrayList;
21+
import java.util.Collection;
2122
import java.util.LinkedHashSet;
22-
import java.util.List;
2323
import java.util.Set;
2424
import java.util.function.Function;
2525
import java.util.function.IntFunction;
@@ -31,10 +31,11 @@
3131
import org.springframework.util.MultiValueMap;
3232

3333
/**
34-
* Collector implementations that provide various reduction operations for
34+
* {@link Collector} implementations that provide various reduction operations for
3535
* {@link MergedAnnotation} instances.
3636
*
3737
* @author Phillip Webb
38+
* @author Sam Brannen
3839
* @since 5.2
3940
*/
4041
public abstract class MergedAnnotationCollectors {
@@ -52,13 +53,16 @@ private MergedAnnotationCollectors() {
5253
* Create a new {@link Collector} that accumulates merged annotations to a
5354
* {@link LinkedHashSet} containing {@linkplain MergedAnnotation#synthesize()
5455
* synthesized} versions.
56+
* <p>The collector returned by this method is effectively equivalent to
57+
* {@code Collectors.mapping(MergedAnnotation::synthesize, Collectors.toCollection(LinkedHashSet::new))}
58+
* but avoids the creation of a composite collector.
5559
* @param <A> the annotation type
5660
* @return a {@link Collector} which collects and synthesizes the
5761
* annotations into a {@link Set}
5862
*/
5963
public static <A extends Annotation> Collector<MergedAnnotation<A>, ?, Set<A>> toAnnotationSet() {
60-
return Collector.of(ArrayList<A>::new, (list, annotation) -> list.add(annotation.synthesize()),
61-
MergedAnnotationCollectors::addAll, LinkedHashSet::new);
64+
return Collector.of(LinkedHashSet::new, (set, annotation) -> set.add(annotation.synthesize()),
65+
MergedAnnotationCollectors::combiner);
6266
}
6367

6468
/**
@@ -90,14 +94,14 @@ private MergedAnnotationCollectors() {
9094
IntFunction<R[]> generator) {
9195

9296
return Collector.of(ArrayList::new, (list, annotation) -> list.add(annotation.synthesize()),
93-
MergedAnnotationCollectors::addAll, list -> list.toArray(generator.apply(list.size())));
97+
MergedAnnotationCollectors::combiner, list -> list.toArray(generator.apply(list.size())));
9498
}
9599

96100
/**
97-
* Create a new {@link Collector} that accumulates merged annotations to an
101+
* Create a new {@link Collector} that accumulates merged annotations to a
98102
* {@link MultiValueMap} with items {@linkplain MultiValueMap#add(Object, Object)
99103
* added} from each merged annotation
100-
* {@link MergedAnnotation#asMap(Adapt...) as a map}.
104+
* {@linkplain MergedAnnotation#asMap(Adapt...) as a map}.
101105
* @param <A> the annotation type
102106
* @param adaptations the adaptations that should be applied to the annotation values
103107
* @return a {@link Collector} which collects and synthesizes the
@@ -111,13 +115,13 @@ private MergedAnnotationCollectors() {
111115
}
112116

113117
/**
114-
* Create a new {@link Collector} that accumulates merged annotations to an
118+
* Create a new {@link Collector} that accumulates merged annotations to a
115119
* {@link MultiValueMap} with items {@linkplain MultiValueMap#add(Object, Object)
116120
* added} from each merged annotation
117-
* {@link MergedAnnotation#asMap(Adapt...) as a map}.
121+
* {@linkplain MergedAnnotation#asMap(Adapt...) as a map}.
118122
* @param <A> the annotation type
119-
* @param adaptations the adaptations that should be applied to the annotation values
120123
* @param finisher the finisher function for the new {@link MultiValueMap}
124+
* @param adaptations the adaptations that should be applied to the annotation values
121125
* @return a {@link Collector} which collects and synthesizes the
122126
* annotations into a {@link LinkedMultiValueMap}
123127
* @see #toMultiValueMap(MergedAnnotation.Adapt...)
@@ -130,21 +134,30 @@ private MergedAnnotationCollectors() {
130134
IDENTITY_FINISH_CHARACTERISTICS : NO_CHARACTERISTICS);
131135
return Collector.of(LinkedMultiValueMap::new,
132136
(map, annotation) -> annotation.asMap(adaptations).forEach(map::add),
133-
MergedAnnotationCollectors::merge, finisher, characteristics);
137+
MergedAnnotationCollectors::combiner, finisher, characteristics);
134138
}
135139

136140

137141
private static boolean isSameInstance(Object instance, Object candidate) {
138142
return instance == candidate;
139143
}
140144

141-
private static <E, L extends List<E>> L addAll(L list, L additions) {
142-
list.addAll(additions);
143-
return list;
145+
/**
146+
* {@link Collector#combiner() Combiner} for collections.
147+
* <p>This method is only invoked if the {@link java.util.stream.Stream} is
148+
* processed in {@linkplain java.util.stream.Stream#parallel() parallel}.
149+
*/
150+
private static <E, C extends Collection<E>> C combiner(C collection, C additions) {
151+
collection.addAll(additions);
152+
return collection;
144153
}
145154

146-
private static <K, V> MultiValueMap<K, V> merge(MultiValueMap<K, V> map,
147-
MultiValueMap<K, V> additions) {
155+
/**
156+
* {@link Collector#combiner() Combiner} for multi-value maps.
157+
* <p>This method is only invoked if the {@link java.util.stream.Stream} is
158+
* processed in {@linkplain java.util.stream.Stream#parallel() parallel}.
159+
*/
160+
private static <K, V> MultiValueMap<K, V> combiner(MultiValueMap<K, V> map, MultiValueMap<K, V> additions) {
148161
map.addAll(additions);
149162
return map;
150163
}

0 commit comments

Comments
 (0)