Skip to content

Commit bcca956

Browse files
authored
Optimize new ArrayList() allocations whenever possible (spring-projects#10573)
To avoid resizing at runtime, it is better to use `ArrayList` with a predefined size. In some cases it is possible from the context of the list we are creating * Fix typos in Javadocs of the affected classes according to IDE suggestions * Use diamond operators for modern Java in the affected classes * pattern matching expressions for `if` where IDE suggested * Use `switch` in one place instead of `if..else`. Again: good suggestion from IDE * Fix Nullability for the router hierarchy * Have to add "redundant" cast in the `XPathRouter` to make NullAway happy
1 parent d58a784 commit bcca956

File tree

65 files changed

+246
-244
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

65 files changed

+246
-244
lines changed

spring-integration-amqp/src/main/java/org/springframework/integration/amqp/inbound/AmqpInboundChannelAdapter.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -491,7 +491,7 @@ public void onMessageBatch(List<Message> messages, @Nullable Channel channel) {
491491
else {
492492
converted = convertPayloads(messages, channel);
493493
if (BatchMode.EXTRACT_PAYLOADS_WITH_HEADERS.equals(AmqpInboundChannelAdapter.this.batchMode)) {
494-
List<Map<String, @Nullable Object>> listHeaders = new ArrayList<>();
494+
List<Map<String, @Nullable Object>> listHeaders = new ArrayList<>(messages.size());
495495
messages.forEach(msg -> listHeaders.add(AmqpInboundChannelAdapter.this.headerMapper
496496
.toHeadersFromRequest(msg.getMessageProperties())));
497497
headers = listHeaders;
@@ -553,7 +553,7 @@ public void onMessageBatch(List<Message> messages, @Nullable Channel channel) {
553553
private @Nullable List<org.springframework.messaging.Message<?>> convertMessages(List<Message> messages,
554554
@Nullable Channel channel) {
555555

556-
List<org.springframework.messaging.Message<?>> converted = new ArrayList<>();
556+
List<org.springframework.messaging.Message<?>> converted = new ArrayList<>(messages.size());
557557
try {
558558
messages.forEach(message -> converted.add(createMessageFromAmqp(message, channel)));
559559
return converted;
@@ -574,7 +574,7 @@ public void onMessageBatch(List<Message> messages, @Nullable Channel channel) {
574574
}
575575

576576
private @Nullable List<?> convertPayloads(List<Message> messages, @Nullable Channel channel) {
577-
List<Object> converted = new ArrayList<>();
577+
List<Object> converted = new ArrayList<>(messages.size());
578578
try {
579579
messages.forEach(message -> converted.add(this.converter.fromMessage(message)));
580580
return converted;

spring-integration-amqp/src/main/java/org/springframework/integration/amqp/support/DefaultAmqpHeaderMapper.java

Lines changed: 27 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616

1717
package org.springframework.integration.amqp.support;
1818

19-
import java.util.ArrayList;
2019
import java.util.Date;
2120
import java.util.HashMap;
2221
import java.util.List;
@@ -62,36 +61,33 @@
6261
*/
6362
public class DefaultAmqpHeaderMapper extends AbstractHeaderMapper<MessageProperties> implements AmqpHeaderMapper {
6463

65-
private static final List<String> STANDARD_HEADER_NAMES = new ArrayList<>();
66-
67-
static {
68-
STANDARD_HEADER_NAMES.add(AmqpHeaders.APP_ID);
69-
STANDARD_HEADER_NAMES.add(AmqpHeaders.CLUSTER_ID);
70-
STANDARD_HEADER_NAMES.add(AmqpHeaders.CONTENT_ENCODING);
71-
STANDARD_HEADER_NAMES.add(AmqpHeaders.CONTENT_LENGTH);
72-
STANDARD_HEADER_NAMES.add(AmqpHeaders.CONTENT_TYPE);
73-
STANDARD_HEADER_NAMES.add(AmqpHeaders.CORRELATION_ID);
74-
STANDARD_HEADER_NAMES.add(AmqpHeaders.DELAY);
75-
STANDARD_HEADER_NAMES.add(AmqpHeaders.DELIVERY_MODE);
76-
STANDARD_HEADER_NAMES.add(AmqpHeaders.DELIVERY_TAG);
77-
STANDARD_HEADER_NAMES.add(AmqpHeaders.EXPIRATION);
78-
STANDARD_HEADER_NAMES.add(AmqpHeaders.MESSAGE_COUNT);
79-
STANDARD_HEADER_NAMES.add(AmqpHeaders.MESSAGE_ID);
80-
STANDARD_HEADER_NAMES.add(AmqpHeaders.RECEIVED_DELAY);
81-
STANDARD_HEADER_NAMES.add(AmqpHeaders.RECEIVED_DELIVERY_MODE);
82-
STANDARD_HEADER_NAMES.add(AmqpHeaders.RECEIVED_EXCHANGE);
83-
STANDARD_HEADER_NAMES.add(AmqpHeaders.RECEIVED_ROUTING_KEY);
84-
STANDARD_HEADER_NAMES.add(AmqpHeaders.REDELIVERED);
85-
STANDARD_HEADER_NAMES.add(AmqpHeaders.REPLY_TO);
86-
STANDARD_HEADER_NAMES.add(AmqpHeaders.TIMESTAMP);
87-
STANDARD_HEADER_NAMES.add(AmqpHeaders.TYPE);
88-
STANDARD_HEADER_NAMES.add(AmqpHeaders.USER_ID);
89-
STANDARD_HEADER_NAMES.add(JsonHeaders.TYPE_ID);
90-
STANDARD_HEADER_NAMES.add(JsonHeaders.CONTENT_TYPE_ID);
91-
STANDARD_HEADER_NAMES.add(JsonHeaders.KEY_TYPE_ID);
92-
STANDARD_HEADER_NAMES.add(AmqpHeaders.SPRING_REPLY_CORRELATION);
93-
STANDARD_HEADER_NAMES.add(AmqpHeaders.SPRING_REPLY_TO_STACK);
94-
}
64+
private static final List<String> STANDARD_HEADER_NAMES =
65+
List.of(AmqpHeaders.APP_ID,
66+
AmqpHeaders.CLUSTER_ID,
67+
AmqpHeaders.CONTENT_ENCODING,
68+
AmqpHeaders.CONTENT_LENGTH,
69+
AmqpHeaders.CONTENT_TYPE,
70+
AmqpHeaders.CORRELATION_ID,
71+
AmqpHeaders.DELAY,
72+
AmqpHeaders.DELIVERY_MODE,
73+
AmqpHeaders.DELIVERY_TAG,
74+
AmqpHeaders.EXPIRATION,
75+
AmqpHeaders.MESSAGE_COUNT,
76+
AmqpHeaders.MESSAGE_ID,
77+
AmqpHeaders.RECEIVED_DELAY,
78+
AmqpHeaders.RECEIVED_DELIVERY_MODE,
79+
AmqpHeaders.RECEIVED_EXCHANGE,
80+
AmqpHeaders.RECEIVED_ROUTING_KEY,
81+
AmqpHeaders.REDELIVERED,
82+
AmqpHeaders.REPLY_TO,
83+
AmqpHeaders.TIMESTAMP,
84+
AmqpHeaders.TYPE,
85+
AmqpHeaders.USER_ID,
86+
JsonHeaders.TYPE_ID,
87+
JsonHeaders.CONTENT_TYPE_ID,
88+
JsonHeaders.KEY_TYPE_ID,
89+
AmqpHeaders.SPRING_REPLY_CORRELATION,
90+
AmqpHeaders.SPRING_REPLY_TO_STACK);
9591

9692
@SuppressWarnings("this-escape")
9793
protected DefaultAmqpHeaderMapper(String @Nullable [] requestHeaderNames, String @Nullable [] replyHeaderNames) {

spring-integration-core/src/main/java/org/springframework/integration/aggregator/ResequencingMessageGroupProcessor.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ public Object processMessageGroup(MessageGroup group) {
4949
if (!messages.isEmpty()) {
5050
List<Message<?>> sorted = new ArrayList<>(messages);
5151
sorted.sort(this.comparator);
52-
ArrayList<Message<?>> partialSequence = new ArrayList<>();
52+
ArrayList<Message<?>> partialSequence = new ArrayList<>(messages.size());
5353
int previousSequence = extractSequenceNumber(sorted.get(0));
5454
int currentSequence = previousSequence;
5555
for (Message<?> message : sorted) {

spring-integration-core/src/main/java/org/springframework/integration/channel/QueueChannel.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -207,8 +207,8 @@ public List<Message<?>> purge(@Nullable MessageSelector selector) {
207207
if (selector == null) {
208208
return this.clear();
209209
}
210-
List<Message<?>> purgedMessages = new ArrayList<>();
211210
Object[] array = this.queue.toArray();
211+
List<Message<?>> purgedMessages = new ArrayList<>(array.length);
212212
for (Object o : array) {
213213
Message<?> message = (Message<?>) o;
214214
if (!selector.accept(message) && this.queue.remove(message)) {

spring-integration-core/src/main/java/org/springframework/integration/codec/kryo/CompositeKryoRegistrar.java

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -29,14 +29,16 @@
2929
* A {@link KryoRegistrar} that delegates and validates registrations across all components.
3030
*
3131
* @author David Turanski
32+
* @author Artem Bilan
33+
*
3234
* @since 4.2
3335
*/
3436
public class CompositeKryoRegistrar extends AbstractKryoRegistrar {
3537

3638
private final List<KryoRegistrar> delegates;
3739

3840
public CompositeKryoRegistrar(List<KryoRegistrar> delegates) {
39-
this.delegates = new ArrayList<KryoRegistrar>(delegates);
41+
this.delegates = new ArrayList<>(delegates);
4042

4143
if (!CollectionUtils.isEmpty(this.delegates)) {
4244
validateRegistrations();
@@ -52,18 +54,19 @@ public void registerTypes(Kryo kryo) {
5254

5355
@Override
5456
public final List<Registration> getRegistrations() {
55-
List<Registration> registrations = new ArrayList<Registration>();
57+
List<Registration> registrations = new ArrayList<>();
5658
for (KryoRegistrar registrar : this.delegates) {
5759
registrations.addAll(registrar.getRegistrations());
5860
}
5961
return registrations;
6062
}
6163

6264
private void validateRegistrations() {
63-
List<Integer> ids = new ArrayList<Integer>();
64-
List<Class<?>> types = new ArrayList<Class<?>>();
65+
List<Registration> registrations = getRegistrations();
66+
List<Integer> ids = new ArrayList<>(registrations.size());
67+
List<Class<?>> types = new ArrayList<>(registrations.size());
6568

66-
for (Registration registration : getRegistrations()) {
69+
for (Registration registration : registrations) {
6770
Assert.isTrue(registration.getId() >= MIN_REGISTRATION_VALUE,
6871
"registration ID must be >= " + MIN_REGISTRATION_VALUE);
6972
if (ids.contains(registration.getId())) {

spring-integration-core/src/main/java/org/springframework/integration/codec/kryo/KryoClassListRegistrar.java

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -64,17 +64,18 @@ public KryoClassListRegistrar(List<Class<?>> classes) {
6464
* @param initialValue the initial value
6565
*/
6666
public void setInitialValue(int initialValue) {
67-
Assert.isTrue(initialValue >= MIN_REGISTRATION_VALUE, "'initialValue' must be >= " + MIN_REGISTRATION_VALUE);
67+
Assert.isTrue(initialValue >= MIN_REGISTRATION_VALUE,
68+
() -> "'initialValue' must be >= " + MIN_REGISTRATION_VALUE);
6869
this.initialValue = initialValue;
6970
}
7071

7172
@Override
7273
public List<Registration> getRegistrations() {
73-
List<Registration> registrations = new ArrayList<>();
74+
List<Registration> registrations = new ArrayList<>(this.registeredClasses.size());
7475
if (!CollectionUtils.isEmpty(this.registeredClasses)) {
7576
for (int i = 0; i < this.registeredClasses.size(); i++) {
76-
registrations.add(new Registration(this.registeredClasses.get(i),
77-
KRYO.getSerializer(this.registeredClasses.get(i)), i + this.initialValue));
77+
Class<?> type = this.registeredClasses.get(i);
78+
registrations.add(new Registration(type, KRYO.getSerializer(type), i + this.initialValue));
7879
}
7980
}
8081
return registrations;

spring-integration-core/src/main/java/org/springframework/integration/codec/kryo/KryoClassMapRegistrar.java

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,23 +30,25 @@
3030
* used to explicitly set the registration ID for each class.
3131
*
3232
* @author David Turanski
33+
* @author Artem Bilan
34+
*
3335
* @since 4.2
3436
*/
3537
public class KryoClassMapRegistrar extends AbstractKryoRegistrar {
3638

3739
private final Map<Integer, Class<?>> registeredClasses;
3840

3941
public KryoClassMapRegistrar(Map<Integer, Class<?>> kryoRegisteredClasses) {
40-
this.registeredClasses = new HashMap<Integer, Class<?>>(kryoRegisteredClasses);
42+
this.registeredClasses = new HashMap<>(kryoRegisteredClasses);
4143
}
4244

4345
@Override
4446
public List<Registration> getRegistrations() {
45-
List<Registration> registrations = new ArrayList<Registration>();
47+
List<Registration> registrations = new ArrayList<>(this.registeredClasses.size());
4648
if (!CollectionUtils.isEmpty(this.registeredClasses)) {
4749
for (Map.Entry<Integer, Class<?>> entry : this.registeredClasses.entrySet()) {
48-
registrations.add(
49-
new Registration(entry.getValue(), KRYO.getSerializer(entry.getValue()), entry.getKey()));
50+
Class<?> type = entry.getValue();
51+
registrations.add(new Registration(type, KRYO.getSerializer(type), entry.getKey()));
5052
}
5153
}
5254
return registrations;

spring-integration-core/src/main/java/org/springframework/integration/codec/kryo/KryoRegistrationRegistrar.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,16 +25,16 @@
2525
* A {@link KryoRegistrar} implementation backed by a List of {@link Registration}.
2626
*
2727
* @author David Turanski
28+
* @author Artem Bilan
29+
*
2830
* @since 4.2
2931
*/
3032
public class KryoRegistrationRegistrar extends AbstractKryoRegistrar {
3133

3234
private final List<Registration> registrations;
3335

3436
public KryoRegistrationRegistrar(List<Registration> registrations) {
35-
this.registrations = registrations != null
36-
? new ArrayList<Registration>(registrations)
37-
: new ArrayList<Registration>();
37+
this.registrations = new ArrayList<>(registrations);
3838
}
3939

4040
@Override

spring-integration-core/src/main/java/org/springframework/integration/config/GlobalChannelInterceptorProcessor.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ public void addMatchingInterceptors(InterceptableChannel channel, String beanNam
120120
LOGGER.debug("Applying global interceptors on channel '" + beanName + "'");
121121
}
122122

123-
List<GlobalChannelInterceptorWrapper> tempInterceptors = new ArrayList<>();
123+
List<GlobalChannelInterceptorWrapper> tempInterceptors = new ArrayList<>(this.positiveOrderInterceptors.size());
124124

125125
this.positiveOrderInterceptors
126126
.forEach(interceptorWrapper ->

spring-integration-core/src/main/java/org/springframework/integration/config/IntegrationComponentScanRegistrar.java

Lines changed: 14 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -76,18 +76,14 @@ public class IntegrationComponentScanRegistrar implements ImportBeanDefinitionRe
7676

7777
private static final String BEAN_NAME = IntegrationComponentScanRegistrar.class.getName();
7878

79-
private final List<TypeFilter> defaultFilters = new ArrayList<>();
79+
private final List<TypeFilter> defaultFilters = List.of(new AnnotationTypeFilter(MessagingGateway.class, true));
8080

8181
@SuppressWarnings("NullAway.Init")
8282
private ResourceLoader resourceLoader;
8383

8484
@SuppressWarnings("NullAway.Init")
8585
private Environment environment;
8686

87-
public IntegrationComponentScanRegistrar() {
88-
this.defaultFilters.add(new AnnotationTypeFilter(MessagingGateway.class, true));
89-
}
90-
9187
@Override
9288
public void setResourceLoader(ResourceLoader resourceLoader) {
9389
this.resourceLoader = resourceLoader;
@@ -132,7 +128,7 @@ protected boolean isCandidateComponent(AnnotatedBeanDefinition beanDefinition) {
132128

133129
};
134130

135-
filter(registry, componentScan, scanner); // NOSONAR - never null
131+
filter(registry, componentScan, scanner);
136132

137133
scanner.setResourceLoader(this.resourceLoader);
138134
scanner.setEnvironment(this.environment);
@@ -151,7 +147,7 @@ protected boolean isCandidateComponent(AnnotatedBeanDefinition beanDefinition) {
151147
private void filter(BeanDefinitionRegistry registry, AnnotationAttributes componentScan,
152148
ClassPathScanningCandidateComponentProvider scanner) {
153149

154-
if (componentScan.getBoolean("useDefaultFilters")) { // NOSONAR - never null
150+
if (componentScan.getBoolean("useDefaultFilters")) {
155151
for (TypeFilter typeFilter : this.defaultFilters) {
156152
scanner.addIncludeFilter(typeFilter);
157153
}
@@ -188,10 +184,11 @@ protected Collection<String> getBasePackages(AnnotationAttributes componentScan,
188184
}
189185

190186
private List<TypeFilter> typeFiltersFor(AnnotationAttributes filter, BeanDefinitionRegistry registry) {
191-
List<TypeFilter> typeFilters = new ArrayList<>();
187+
Class<?>[] classes = filter.getClassArray("classes");
188+
List<TypeFilter> typeFilters = new ArrayList<>(classes.length);
192189
FilterType filterType = filter.getEnum("type");
193190

194-
for (Class<?> filterClass : filter.getClassArray("classes")) {
191+
for (Class<?> filterClass : classes) {
195192
switch (filterType) {
196193
case ANNOTATION -> {
197194
Assert.isAssignable(Annotation.class, filterClass,
@@ -230,23 +227,23 @@ private static void invokeAwareMethods(Object parserStrategyBean, Environment en
230227
ResourceLoader resourceLoader, BeanDefinitionRegistry registry) {
231228

232229
if (parserStrategyBean instanceof Aware) {
233-
if (parserStrategyBean instanceof BeanClassLoaderAware) {
230+
if (parserStrategyBean instanceof BeanClassLoaderAware beanClassLoaderAware) {
234231
ClassLoader classLoader =
235232
registry instanceof ConfigurableBeanFactory
236233
? ((ConfigurableBeanFactory) registry).getBeanClassLoader()
237234
: resourceLoader.getClassLoader();
238235
if (classLoader != null) {
239-
((BeanClassLoaderAware) parserStrategyBean).setBeanClassLoader(classLoader);
236+
beanClassLoaderAware.setBeanClassLoader(classLoader);
240237
}
241238
}
242-
if (parserStrategyBean instanceof BeanFactoryAware && registry instanceof BeanFactory) {
243-
((BeanFactoryAware) parserStrategyBean).setBeanFactory((BeanFactory) registry);
239+
if (parserStrategyBean instanceof BeanFactoryAware beanFactoryAware && registry instanceof BeanFactory) {
240+
beanFactoryAware.setBeanFactory((BeanFactory) registry);
244241
}
245-
if (parserStrategyBean instanceof EnvironmentAware) {
246-
((EnvironmentAware) parserStrategyBean).setEnvironment(environment);
242+
if (parserStrategyBean instanceof EnvironmentAware environmentAware) {
243+
environmentAware.setEnvironment(environment);
247244
}
248-
if (parserStrategyBean instanceof ResourceLoaderAware) {
249-
((ResourceLoaderAware) parserStrategyBean).setResourceLoader(resourceLoader);
245+
if (parserStrategyBean instanceof ResourceLoaderAware resourceLoaderAware) {
246+
resourceLoaderAware.setResourceLoader(resourceLoader);
250247
}
251248
}
252249
}

0 commit comments

Comments
 (0)