From 4a147d26fcd086ffc4d495e34b6d1b54854c345b Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Mon, 30 Jul 2018 22:07:31 +0200 Subject: [PATCH] Initialize pre-filled HashMaps with large enough capacity Empty Maps are preferably initialized without capacity (not initializing them at all or lazily initializing with default capacity when needed). Issue: SPR-17105 --- .../factory/config/ConstructorArgumentValues.java | 2 +- .../factory/support/AbstractBeanDefinition.java | 2 +- .../cache/interceptor/CacheAspectSupport.java | 2 +- .../concurrent/ConcurrentTaskExecutor.java | 10 +++++++--- .../validation/AbstractBindingResult.java | 4 ++-- .../core/AttributeAccessorSupport.java | 2 +- .../jdbc/core/simple/AbstractJdbcInsert.java | 4 ++-- .../springframework/messaging/MessageHeaders.java | 2 +- .../simp/broker/AbstractSubscriptionRegistry.java | 4 ++-- .../AbstractMessageBrokerConfiguration.java | 2 +- .../simp/user/MultiServerUserRegistry.java | 2 +- .../org/springframework/http/HttpHeaders.java | 2 +- .../java/org/springframework/http/HttpMethod.java | 4 ++-- .../http/server/DefaultPathContainer.java | 2 +- .../web/util/HierarchicalUriComponents.java | 14 +++----------- .../web/util/HtmlCharacterEntityReferences.java | 2 +- .../web/util/OpaqueUriComponents.java | 2 +- .../function/client/DefaultWebClient.java | 2 +- .../adapter/NettyWebSocketSessionSupport.java | 15 ++++++++------- 19 files changed, 38 insertions(+), 41 deletions(-) diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/config/ConstructorArgumentValues.java b/spring-beans/src/main/java/org/springframework/beans/factory/config/ConstructorArgumentValues.java index db4ae1e6c12..760b9534d90 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/config/ConstructorArgumentValues.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/config/ConstructorArgumentValues.java @@ -43,7 +43,7 @@ import org.springframework.util.ObjectUtils; */ public class ConstructorArgumentValues { - private final Map indexedArgumentValues = new LinkedHashMap<>(0); + private final Map indexedArgumentValues = new LinkedHashMap<>(); private final List genericArgumentValues = new ArrayList<>(); diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractBeanDefinition.java b/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractBeanDefinition.java index d02997186cc..f0c463b9120 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractBeanDefinition.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractBeanDefinition.java @@ -158,7 +158,7 @@ public abstract class AbstractBeanDefinition extends BeanMetadataAttributeAccess private boolean primary = false; - private final Map qualifiers = new LinkedHashMap<>(0); + private final Map qualifiers = new LinkedHashMap<>(); @Nullable private Supplier instanceSupplier; diff --git a/spring-context/src/main/java/org/springframework/cache/interceptor/CacheAspectSupport.java b/spring-context/src/main/java/org/springframework/cache/interceptor/CacheAspectSupport.java index 47c4694857c..f8156ab095d 100644 --- a/spring-context/src/main/java/org/springframework/cache/interceptor/CacheAspectSupport.java +++ b/spring-context/src/main/java/org/springframework/cache/interceptor/CacheAspectSupport.java @@ -410,7 +410,7 @@ public abstract class CacheAspectSupport extends AbstractCacheInvoker Object cacheValue; Object returnValue; - if (cacheHit != null && cachePutRequests.isEmpty() && !hasCachePut(contexts)) { + if (cacheHit != null && !hasCachePut(contexts)) { // If there are no put requests, just use the cache hit cacheValue = cacheHit.get(); returnValue = wrapCacheValue(method, cacheValue); diff --git a/spring-context/src/main/java/org/springframework/scheduling/concurrent/ConcurrentTaskExecutor.java b/spring-context/src/main/java/org/springframework/scheduling/concurrent/ConcurrentTaskExecutor.java index d10f162cd31..592e3af73b5 100644 --- a/spring-context/src/main/java/org/springframework/scheduling/concurrent/ConcurrentTaskExecutor.java +++ b/spring-context/src/main/java/org/springframework/scheduling/concurrent/ConcurrentTaskExecutor.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2017 the original author or authors. + * Copyright 2002-2018 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -230,17 +230,21 @@ public class ConcurrentTaskExecutor implements AsyncListenableTaskExecutor, Sche protected static class ManagedTaskBuilder { public static Runnable buildManagedTask(Runnable task, String identityName) { - Map properties = new HashMap<>(2); + Map properties; if (task instanceof SchedulingAwareRunnable) { + properties = new HashMap<>(4); properties.put(ManagedTask.LONGRUNNING_HINT, Boolean.toString(((SchedulingAwareRunnable) task).isLongLived())); } + else { + properties = new HashMap<>(2); + } properties.put(ManagedTask.IDENTITY_NAME, identityName); return ManagedExecutors.managedTask(task, properties, null); } public static Callable buildManagedTask(Callable task, String identityName) { - Map properties = new HashMap<>(1); + Map properties = new HashMap<>(2); properties.put(ManagedTask.IDENTITY_NAME, identityName); return ManagedExecutors.managedTask(task, properties, null); } diff --git a/spring-context/src/main/java/org/springframework/validation/AbstractBindingResult.java b/spring-context/src/main/java/org/springframework/validation/AbstractBindingResult.java index ece1663b273..bc754bf937b 100644 --- a/spring-context/src/main/java/org/springframework/validation/AbstractBindingResult.java +++ b/spring-context/src/main/java/org/springframework/validation/AbstractBindingResult.java @@ -52,9 +52,9 @@ public abstract class AbstractBindingResult extends AbstractErrors implements Bi private final List errors = new LinkedList<>(); - private final Map> fieldTypes = new HashMap<>(0); + private final Map> fieldTypes = new HashMap<>(); - private final Map fieldValues = new HashMap<>(0); + private final Map fieldValues = new HashMap<>(); private final Set suppressedFields = new HashSet<>(); diff --git a/spring-core/src/main/java/org/springframework/core/AttributeAccessorSupport.java b/spring-core/src/main/java/org/springframework/core/AttributeAccessorSupport.java index 5f4f515e23f..1653f113c48 100644 --- a/spring-core/src/main/java/org/springframework/core/AttributeAccessorSupport.java +++ b/spring-core/src/main/java/org/springframework/core/AttributeAccessorSupport.java @@ -38,7 +38,7 @@ import org.springframework.util.StringUtils; public abstract class AttributeAccessorSupport implements AttributeAccessor, Serializable { /** Map with String keys and Object values. */ - private final Map attributes = new LinkedHashMap<>(0); + private final Map attributes = new LinkedHashMap<>(); @Override diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/core/simple/AbstractJdbcInsert.java b/spring-jdbc/src/main/java/org/springframework/jdbc/core/simple/AbstractJdbcInsert.java index d7c4509602f..8ef5fbbb3b1 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/core/simple/AbstractJdbcInsert.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/core/simple/AbstractJdbcInsert.java @@ -465,7 +465,7 @@ public abstract class AbstractJdbcInsert { if (keyQuery.toUpperCase().startsWith("RETURNING")) { Long key = getJdbcTemplate().queryForObject( getInsertString() + " " + keyQuery, values.toArray(), Long.class); - Map keys = new HashMap<>(1); + Map keys = new HashMap<>(2); keys.put(getGeneratedKeyNames()[0], key); keyHolder.getKeyList().add(keys); } @@ -484,7 +484,7 @@ public abstract class AbstractJdbcInsert { //Get the key Statement keyStmt = null; ResultSet rs = null; - Map keys = new HashMap<>(1); + Map keys = new HashMap<>(2); try { keyStmt = con.createStatement(); rs = keyStmt.executeQuery(keyQuery); diff --git a/spring-messaging/src/main/java/org/springframework/messaging/MessageHeaders.java b/spring-messaging/src/main/java/org/springframework/messaging/MessageHeaders.java index 3645238232b..8ac2d06be81 100644 --- a/spring-messaging/src/main/java/org/springframework/messaging/MessageHeaders.java +++ b/spring-messaging/src/main/java/org/springframework/messaging/MessageHeaders.java @@ -164,7 +164,7 @@ public class MessageHeaders implements Map, Serializable { * @param keysToIgnore the keys of the entries to ignore */ private MessageHeaders(MessageHeaders original, Set keysToIgnore) { - this.headers = new HashMap<>(original.headers.size() - keysToIgnore.size()); + this.headers = new HashMap<>(original.headers.size()); original.headers.forEach((key, value) -> { if (!keysToIgnore.contains(key)) { this.headers.put(key, value); diff --git a/spring-messaging/src/main/java/org/springframework/messaging/simp/broker/AbstractSubscriptionRegistry.java b/spring-messaging/src/main/java/org/springframework/messaging/simp/broker/AbstractSubscriptionRegistry.java index 83bbbd7d935..b2facbc0922 100644 --- a/spring-messaging/src/main/java/org/springframework/messaging/simp/broker/AbstractSubscriptionRegistry.java +++ b/spring-messaging/src/main/java/org/springframework/messaging/simp/broker/AbstractSubscriptionRegistry.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2017 the original author or authors. + * Copyright 2002-2018 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -38,7 +38,7 @@ import org.springframework.util.MultiValueMap; public abstract class AbstractSubscriptionRegistry implements SubscriptionRegistry { private static final MultiValueMap EMPTY_MAP = - CollectionUtils.unmodifiableMultiValueMap(new LinkedMultiValueMap<>(0)); + CollectionUtils.unmodifiableMultiValueMap(new LinkedMultiValueMap<>()); protected final Log logger = SimpLogging.forLogName(getClass()); diff --git a/spring-messaging/src/main/java/org/springframework/messaging/simp/config/AbstractMessageBrokerConfiguration.java b/spring-messaging/src/main/java/org/springframework/messaging/simp/config/AbstractMessageBrokerConfiguration.java index 26459851d3c..603179393e0 100644 --- a/spring-messaging/src/main/java/org/springframework/messaging/simp/config/AbstractMessageBrokerConfiguration.java +++ b/spring-messaging/src/main/java/org/springframework/messaging/simp/config/AbstractMessageBrokerConfiguration.java @@ -317,7 +317,7 @@ public abstract class AbstractMessageBrokerConfiguration implements ApplicationC if (handler == null) { return null; } - Map subscriptions = new HashMap<>(1); + Map subscriptions = new HashMap<>(4); String destination = getBrokerRegistry().getUserDestinationBroadcast(); if (destination != null) { subscriptions.put(destination, userDestinationMessageHandler()); diff --git a/spring-messaging/src/main/java/org/springframework/messaging/simp/user/MultiServerUserRegistry.java b/spring-messaging/src/main/java/org/springframework/messaging/simp/user/MultiServerUserRegistry.java index 7d943d44c6d..de438e023f3 100644 --- a/spring-messaging/src/main/java/org/springframework/messaging/simp/user/MultiServerUserRegistry.java +++ b/spring-messaging/src/main/java/org/springframework/messaging/simp/user/MultiServerUserRegistry.java @@ -545,7 +545,7 @@ public class MultiServerUserRegistry implements SimpUserRegistry, SmartApplicati private class SessionLookup { public Map findSessions(String userName) { - Map map = new HashMap<>(1); + Map map = new HashMap<>(4); SimpUser user = localRegistry.getUser(userName); if (user != null) { for (SimpSession session : user.getSessions()) { diff --git a/spring-web/src/main/java/org/springframework/http/HttpHeaders.java b/spring-web/src/main/java/org/springframework/http/HttpHeaders.java index 6643c0f5f25..dded0c19929 100644 --- a/spring-web/src/main/java/org/springframework/http/HttpHeaders.java +++ b/spring-web/src/main/java/org/springframework/http/HttpHeaders.java @@ -78,7 +78,7 @@ public class HttpHeaders implements MultiValueMap, Serializable /** * The empty {@code HttpHeaders} instance (immutable). */ - public static final HttpHeaders EMPTY = new HttpHeaders(new LinkedHashMap<>(0), true); + public static final HttpHeaders EMPTY = new HttpHeaders(new LinkedHashMap<>(), true); /** * The HTTP {@code Accept} header field name. * @see Section 5.3.2 of RFC 7231 diff --git a/spring-web/src/main/java/org/springframework/http/HttpMethod.java b/spring-web/src/main/java/org/springframework/http/HttpMethod.java index 2ddb36b28a8..bd2d1ef182e 100644 --- a/spring-web/src/main/java/org/springframework/http/HttpMethod.java +++ b/spring-web/src/main/java/org/springframework/http/HttpMethod.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2002-2018 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -35,7 +35,7 @@ public enum HttpMethod { GET, HEAD, POST, PUT, PATCH, DELETE, OPTIONS, TRACE; - private static final Map mappings = new HashMap<>(8); + private static final Map mappings = new HashMap<>(16); static { for (HttpMethod httpMethod : values()) { diff --git a/spring-web/src/main/java/org/springframework/http/server/DefaultPathContainer.java b/spring-web/src/main/java/org/springframework/http/server/DefaultPathContainer.java index 9dff04e405e..2dc03b4da14 100644 --- a/spring-web/src/main/java/org/springframework/http/server/DefaultPathContainer.java +++ b/spring-web/src/main/java/org/springframework/http/server/DefaultPathContainer.java @@ -38,7 +38,7 @@ import org.springframework.util.StringUtils; */ final class DefaultPathContainer implements PathContainer { - private static final MultiValueMap EMPTY_MAP = new LinkedMultiValueMap<>(0); + private static final MultiValueMap EMPTY_MAP = new LinkedMultiValueMap<>(); private static final PathContainer EMPTY_PATH = new DefaultPathContainer("", Collections.emptyList()); diff --git a/spring-web/src/main/java/org/springframework/web/util/HierarchicalUriComponents.java b/spring-web/src/main/java/org/springframework/web/util/HierarchicalUriComponents.java index 0a17b6858fe..97ab202f0ae 100644 --- a/spring-web/src/main/java/org/springframework/web/util/HierarchicalUriComponents.java +++ b/spring-web/src/main/java/org/springframework/web/util/HierarchicalUriComponents.java @@ -55,54 +55,46 @@ final class HierarchicalUriComponents extends UriComponents { private static final String PATH_DELIMITER_STRING = "/"; + private static final MultiValueMap EMPTY_QUERY_PARAMS = + CollectionUtils.unmodifiableMultiValueMap(new LinkedMultiValueMap<>()); + /** * Represents an empty path. */ static final PathComponent NULL_PATH_COMPONENT = new PathComponent() { - @Override public String getPath() { return ""; } - @Override public List getPathSegments() { return Collections.emptyList(); } - @Override public PathComponent encode(BiFunction encoder) { return this; } - @Override public void verify() { } - @Override public PathComponent expand(UriTemplateVariables uriVariables, @Nullable UnaryOperator encoder) { return this; } - @Override public void copyToUriComponentsBuilder(UriComponentsBuilder builder) { } - @Override public boolean equals(Object other) { return (this == other); } - @Override public int hashCode() { return getClass().hashCode(); } }; - private static final MultiValueMap EMPTY_QUERY_PARAMS = - CollectionUtils.unmodifiableMultiValueMap(new LinkedMultiValueMap<>(0)); - @Nullable private final String userInfo; diff --git a/spring-web/src/main/java/org/springframework/web/util/HtmlCharacterEntityReferences.java b/spring-web/src/main/java/org/springframework/web/util/HtmlCharacterEntityReferences.java index a7ac1c77a05..3afe5e8f066 100644 --- a/spring-web/src/main/java/org/springframework/web/util/HtmlCharacterEntityReferences.java +++ b/spring-web/src/main/java/org/springframework/web/util/HtmlCharacterEntityReferences.java @@ -55,7 +55,7 @@ class HtmlCharacterEntityReferences { private final String[] characterToEntityReferenceMap = new String[3000]; - private final Map entityReferenceToCharacterMap = new HashMap<>(252); + private final Map entityReferenceToCharacterMap = new HashMap<>(512); /** diff --git a/spring-web/src/main/java/org/springframework/web/util/OpaqueUriComponents.java b/spring-web/src/main/java/org/springframework/web/util/OpaqueUriComponents.java index 22f4e1e8e16..835606fad4f 100644 --- a/spring-web/src/main/java/org/springframework/web/util/OpaqueUriComponents.java +++ b/spring-web/src/main/java/org/springframework/web/util/OpaqueUriComponents.java @@ -38,7 +38,7 @@ import org.springframework.util.ObjectUtils; @SuppressWarnings("serial") final class OpaqueUriComponents extends UriComponents { - private static final MultiValueMap QUERY_PARAMS_NONE = new LinkedMultiValueMap<>(0); + private static final MultiValueMap QUERY_PARAMS_NONE = new LinkedMultiValueMap<>(); @Nullable private final String ssp; diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/function/client/DefaultWebClient.java b/spring-webflux/src/main/java/org/springframework/web/reactive/function/client/DefaultWebClient.java index accadf16512..3f09804079b 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/function/client/DefaultWebClient.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/function/client/DefaultWebClient.java @@ -349,7 +349,7 @@ class DefaultWebClient implements WebClient { private MultiValueMap initCookies() { if (CollectionUtils.isEmpty(this.cookies)) { - return (defaultCookies != null ? defaultCookies : new LinkedMultiValueMap<>(0)); + return (defaultCookies != null ? defaultCookies : new LinkedMultiValueMap<>()); } else if (CollectionUtils.isEmpty(defaultCookies)) { return this.cookies; diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/socket/adapter/NettyWebSocketSessionSupport.java b/spring-webflux/src/main/java/org/springframework/web/reactive/socket/adapter/NettyWebSocketSessionSupport.java index cda4d011aa9..4ded689bb9a 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/socket/adapter/NettyWebSocketSessionSupport.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/socket/adapter/NettyWebSocketSessionSupport.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.web.reactive.socket.adapter; import java.util.HashMap; @@ -49,14 +50,14 @@ public abstract class NettyWebSocketSessionSupport extends AbstractWebSocketS protected static final int DEFAULT_FRAME_MAX_SIZE = 64 * 1024; - private static final Map, WebSocketMessage.Type> MESSAGE_TYPES; + private static final Map, WebSocketMessage.Type> messageTypes; static { - MESSAGE_TYPES = new HashMap<>(4); - MESSAGE_TYPES.put(TextWebSocketFrame.class, WebSocketMessage.Type.TEXT); - MESSAGE_TYPES.put(BinaryWebSocketFrame.class, WebSocketMessage.Type.BINARY); - MESSAGE_TYPES.put(PingWebSocketFrame.class, WebSocketMessage.Type.PING); - MESSAGE_TYPES.put(PongWebSocketFrame.class, WebSocketMessage.Type.PONG); + messageTypes = new HashMap<>(8); + messageTypes.put(TextWebSocketFrame.class, WebSocketMessage.Type.TEXT); + messageTypes.put(BinaryWebSocketFrame.class, WebSocketMessage.Type.BINARY); + messageTypes.put(PingWebSocketFrame.class, WebSocketMessage.Type.PING); + messageTypes.put(PongWebSocketFrame.class, WebSocketMessage.Type.PONG); } @@ -73,7 +74,7 @@ public abstract class NettyWebSocketSessionSupport extends AbstractWebSocketS protected WebSocketMessage toMessage(WebSocketFrame frame) { DataBuffer payload = bufferFactory().wrap(frame.content()); - return new WebSocketMessage(MESSAGE_TYPES.get(frame.getClass()), payload); + return new WebSocketMessage(messageTypes.get(frame.getClass()), payload); } protected WebSocketFrame toFrame(WebSocketMessage message) {