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.
1818
1919import java .lang .annotation .Annotation ;
2020import java .util .ArrayList ;
21+ import java .util .Collection ;
2122import java .util .LinkedHashSet ;
22- import java .util .List ;
2323import java .util .Set ;
2424import java .util .function .Function ;
2525import java .util .function .IntFunction ;
3131import 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 */
4041public 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