From ff11467a0c62986cc26eca7b94c3d58ae7bc0e3d Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Tue, 25 Aug 2020 19:26:18 +0200 Subject: [PATCH] Avoid resizing of fixed-size HashMap/LinkedHashMap variants Closes gh-25349 --- .../aop/framework/CglibAopProxy.java | 4 +- .../org/springframework/beans/BeanUtils.java | 3 +- .../beans/factory/config/MapFactoryBean.java | 6 +-- .../support/BeanDefinitionValueResolver.java | 4 +- .../support/DefaultListableBeanFactory.java | 12 ++--- .../interceptor/KeyGeneratorAdapter.java | 1 - .../jmx/access/MBeanClientInterceptor.java | 7 +-- .../InterfaceBasedMBeanInfoAssembler.java | 4 +- .../GenericConversionServiceBenchmark.java | 10 +++-- .../core/annotation/AnnotationUtils.java | 4 +- .../org/springframework/core/codec/Hints.java | 8 ++-- .../AnnotationMetadataReadingVisitor.java | 2 +- .../MethodMetadataReadingVisitor.java | 2 +- .../springframework/util/CollectionUtils.java | 45 +++++++++++++++++-- .../util/LinkedCaseInsensitiveMap.java | 25 ++++++----- .../util/LinkedMultiValueMap.java | 8 ++-- .../util/MultiValueMapAdapter.java | 3 +- .../jdbc/core/JdbcTemplate.java | 3 +- .../core/metadata/CallMetaDataContext.java | 16 +++---- .../core/metadata/TableMetaDataContext.java | 6 +-- .../lookup/AbstractRoutingDataSource.java | 4 +- .../rowset/ResultSetWrappingSqlRowSet.java | 6 +-- .../messaging/MessageHeaders.java | 5 ++- .../AbstractMethodMessageHandler.java | 4 +- .../AbstractMethodMessageHandler.java | 2 +- .../RSocketFrameTypeMessageCondition.java | 6 +-- .../messaging/simp/stomp/StompHeaders.java | 7 +-- .../simp/user/MultiServerUserRegistry.java | 5 ++- .../support/NativeMessageHeaderAccessor.java | 4 +- .../oxm/xstream/XStreamMarshaller.java | 4 +- .../AbstractRoutingConnectionFactory.java | 6 +-- .../r2dbc/core/DefaultDatabaseClient.java | 5 +-- .../r2dbc/core/binding/Bindings.java | 4 +- .../HttpComponentsHeadersAdapter.java | 4 +- .../client/reactive/JettyHeadersAdapter.java | 4 +- .../client/reactive/NettyHeadersAdapter.java | 6 +-- .../codec/json/AbstractJackson2Encoder.java | 4 +- .../AbstractJackson2HttpMessageConverter.java | 4 +- .../server/reactive/JettyHeadersAdapter.java | 4 +- .../server/reactive/NettyHeadersAdapter.java | 4 +- .../server/reactive/TomcatHeadersAdapter.java | 6 +-- .../reactive/UndertowHeadersAdapter.java | 6 +-- .../cors/UrlBasedCorsConfigurationSource.java | 4 +- ...RequestParamMapMethodArgumentResolver.java | 7 +-- .../springframework/web/util/UriTemplate.java | 4 +- .../springframework/web/util/UriUtils.java | 6 +-- .../web/util/UrlPathHelper.java | 4 +- .../web/reactive/config/CorsRegistry.java | 4 +- .../function/client/DefaultWebClient.java | 2 +- .../client/DefaultWebClientBuilder.java | 2 +- .../RequestMethodsRequestCondition.java | 4 +- .../RenderingResponseIntegrationTests.java | 6 +-- .../springframework/web/servlet/FlashMap.java | 4 +- .../config/annotation/CorsRegistry.java | 4 +- .../RequestMethodsRequestCondition.java | 4 +- .../web/servlet/view/AbstractView.java | 4 +- .../view/json/MappingJackson2JsonView.java | 5 +-- .../web/socket/WebSocketExtension.java | 3 +- 58 files changed, 195 insertions(+), 149 deletions(-) diff --git a/spring-aop/src/main/java/org/springframework/aop/framework/CglibAopProxy.java b/spring-aop/src/main/java/org/springframework/aop/framework/CglibAopProxy.java index 0c60f7926d..6786472896 100644 --- a/spring-aop/src/main/java/org/springframework/aop/framework/CglibAopProxy.java +++ b/spring-aop/src/main/java/org/springframework/aop/framework/CglibAopProxy.java @@ -21,7 +21,6 @@ import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.lang.reflect.UndeclaredThrowableException; import java.util.Collections; -import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; @@ -53,6 +52,7 @@ import org.springframework.core.SmartClassLoader; import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.ClassUtils; +import org.springframework.util.CollectionUtils; import org.springframework.util.ObjectUtils; import org.springframework.util.ReflectionUtils; @@ -325,7 +325,7 @@ class CglibAopProxy implements AopProxy, Serializable { if (isStatic && isFrozen) { Method[] methods = rootClass.getMethods(); Callback[] fixedCallbacks = new Callback[methods.length]; - this.fixedInterceptorMap = new HashMap<>(methods.length); + this.fixedInterceptorMap = CollectionUtils.newHashMap(methods.length); // TODO: small memory optimization here (can skip creation for methods with no advice) for (int x = 0; x < methods.length; x++) { diff --git a/spring-beans/src/main/java/org/springframework/beans/BeanUtils.java b/spring-beans/src/main/java/org/springframework/beans/BeanUtils.java index e467866c53..039784a6c1 100644 --- a/spring-beans/src/main/java/org/springframework/beans/BeanUtils.java +++ b/spring-beans/src/main/java/org/springframework/beans/BeanUtils.java @@ -49,6 +49,7 @@ import org.springframework.core.ResolvableType; import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.ClassUtils; +import org.springframework.util.CollectionUtils; import org.springframework.util.ConcurrentReferenceHashMap; import org.springframework.util.ReflectionUtils; import org.springframework.util.StringUtils; @@ -792,7 +793,7 @@ public abstract class BeanUtils { } List parameters = kotlinConstructor.getParameters(); - Map argParameters = new HashMap<>(parameters.size()); + Map argParameters = CollectionUtils.newHashMap(parameters.size()); Assert.isTrue(args.length <= parameters.size(), "Number of provided arguments should be less of equals than number of constructor parameters"); for (int i = 0 ; i < args.length ; i++) { diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/config/MapFactoryBean.java b/spring-beans/src/main/java/org/springframework/beans/factory/config/MapFactoryBean.java index 6c11998e41..b02673c8b7 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/config/MapFactoryBean.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/config/MapFactoryBean.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2017 the original author or authors. + * Copyright 2002-2020 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. @@ -16,13 +16,13 @@ package org.springframework.beans.factory.config; -import java.util.LinkedHashMap; import java.util.Map; import org.springframework.beans.BeanUtils; import org.springframework.beans.TypeConverter; import org.springframework.core.ResolvableType; import org.springframework.lang.Nullable; +import org.springframework.util.CollectionUtils; /** * Simple factory for shared Map instances. Allows for central setup @@ -85,7 +85,7 @@ public class MapFactoryBean extends AbstractFactoryBean> { result = BeanUtils.instantiateClass(this.targetMapClass); } else { - result = new LinkedHashMap<>(this.sourceMap.size()); + result = CollectionUtils.newLinkedHashMap(this.sourceMap.size()); } Class keyType = null; Class valueType = null; diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/support/BeanDefinitionValueResolver.java b/spring-beans/src/main/java/org/springframework/beans/factory/support/BeanDefinitionValueResolver.java index 124f1fa84f..be9667b19a 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/support/BeanDefinitionValueResolver.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/support/BeanDefinitionValueResolver.java @@ -18,7 +18,6 @@ package org.springframework.beans.factory.support; import java.lang.reflect.Array; import java.util.ArrayList; -import java.util.LinkedHashMap; import java.util.LinkedHashSet; import java.util.List; import java.util.Map; @@ -42,6 +41,7 @@ import org.springframework.beans.factory.config.RuntimeBeanReference; import org.springframework.beans.factory.config.TypedStringValue; import org.springframework.lang.Nullable; import org.springframework.util.ClassUtils; +import org.springframework.util.CollectionUtils; import org.springframework.util.ObjectUtils; import org.springframework.util.StringUtils; @@ -447,7 +447,7 @@ class BeanDefinitionValueResolver { * For each element in the managed map, resolve reference if necessary. */ private Map resolveManagedMap(Object argName, Map mm) { - Map resolved = new LinkedHashMap<>(mm.size()); + Map resolved = CollectionUtils.newLinkedHashMap(mm.size()); mm.forEach((key, value) -> { Object resolvedKey = resolveValueIfNecessary(argName, key); Object resolvedValue = resolveValueIfNecessary(new KeyedArgName(argName, key), value); diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/support/DefaultListableBeanFactory.java b/spring-beans/src/main/java/org/springframework/beans/factory/support/DefaultListableBeanFactory.java index d484171d29..dc79d3c6ad 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/support/DefaultListableBeanFactory.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/support/DefaultListableBeanFactory.java @@ -33,7 +33,6 @@ import java.util.Collection; import java.util.Comparator; import java.util.IdentityHashMap; import java.util.Iterator; -import java.util.LinkedHashMap; import java.util.LinkedHashSet; import java.util.List; import java.util.Map; @@ -81,6 +80,7 @@ import org.springframework.core.metrics.StartupStep; import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.ClassUtils; +import org.springframework.util.CollectionUtils; import org.springframework.util.CompositeIterator; import org.springframework.util.ObjectUtils; import org.springframework.util.StringUtils; @@ -476,7 +476,7 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto if (beanNames.length == 0) { return Stream.empty(); } - Map matchingBeans = new LinkedHashMap<>(beanNames.length); + Map matchingBeans = CollectionUtils.newLinkedHashMap(beanNames.length); for (String beanName : beanNames) { Object beanInstance = getBean(beanName); if (!(beanInstance instanceof NullBean)) { @@ -665,7 +665,7 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto @Nullable Class type, boolean includeNonSingletons, boolean allowEagerInit) throws BeansException { String[] beanNames = getBeanNamesForType(type, includeNonSingletons, allowEagerInit); - Map result = new LinkedHashMap<>(beanNames.length); + Map result = CollectionUtils.newLinkedHashMap(beanNames.length); for (String beanName : beanNames) { try { Object beanInstance = getBean(beanName); @@ -715,7 +715,7 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto @Override public Map getBeansWithAnnotation(Class annotationType) { String[] beanNames = getBeanNamesForAnnotation(annotationType); - Map result = new LinkedHashMap<>(beanNames.length); + Map result = CollectionUtils.newLinkedHashMap(beanNames.length); for (String beanName : beanNames) { Object beanInstance = getBean(beanName); if (!(beanInstance instanceof NullBean)) { @@ -1235,7 +1235,7 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto return new NamedBeanHolder<>(beanName, (T) getBean(beanName, requiredType.toClass(), args)); } else if (candidateNames.length > 1) { - Map candidates = new LinkedHashMap<>(candidateNames.length); + Map candidates = CollectionUtils.newLinkedHashMap(candidateNames.length); for (String beanName : candidateNames) { if (containsSingleton(beanName) && args == null) { Object beanInstance = getBean(beanName); @@ -1532,7 +1532,7 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto String[] candidateNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors( this, requiredType, true, descriptor.isEager()); - Map result = new LinkedHashMap<>(candidateNames.length); + Map result = CollectionUtils.newLinkedHashMap(candidateNames.length); for (Map.Entry, Object> classObjectEntry : this.resolvableDependencies.entrySet()) { Class autowiringType = classObjectEntry.getKey(); if (autowiringType.isAssignableFrom(requiredType)) { diff --git a/spring-context-support/src/main/java/org/springframework/cache/jcache/interceptor/KeyGeneratorAdapter.java b/spring-context-support/src/main/java/org/springframework/cache/jcache/interceptor/KeyGeneratorAdapter.java index 55a00d2c51..3fcfe9fc58 100644 --- a/spring-context-support/src/main/java/org/springframework/cache/jcache/interceptor/KeyGeneratorAdapter.java +++ b/spring-context-support/src/main/java/org/springframework/cache/jcache/interceptor/KeyGeneratorAdapter.java @@ -101,7 +101,6 @@ class KeyGeneratorAdapter implements KeyGenerator { } } - @SuppressWarnings("unchecked") private static Object doGenerate(KeyGenerator keyGenerator, CacheKeyInvocationContext context) { List parameters = new ArrayList<>(); for (CacheInvocationParameter param : context.getKeyParameters()) { diff --git a/spring-context/src/main/java/org/springframework/jmx/access/MBeanClientInterceptor.java b/spring-context/src/main/java/org/springframework/jmx/access/MBeanClientInterceptor.java index e80b4284d9..816459b3e5 100644 --- a/spring-context/src/main/java/org/springframework/jmx/access/MBeanClientInterceptor.java +++ b/spring-context/src/main/java/org/springframework/jmx/access/MBeanClientInterceptor.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2020 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. @@ -66,6 +66,7 @@ import org.springframework.jmx.support.ObjectNameManager; import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.ClassUtils; +import org.springframework.util.CollectionUtils; import org.springframework.util.ReflectionUtils; import org.springframework.util.StringUtils; @@ -301,13 +302,13 @@ public class MBeanClientInterceptor MBeanInfo info = server.getMBeanInfo(this.objectName); MBeanAttributeInfo[] attributeInfo = info.getAttributes(); - this.allowedAttributes = new HashMap<>(attributeInfo.length); + this.allowedAttributes = CollectionUtils.newHashMap(attributeInfo.length); for (MBeanAttributeInfo infoEle : attributeInfo) { this.allowedAttributes.put(infoEle.getName(), infoEle); } MBeanOperationInfo[] operationInfo = info.getOperations(); - this.allowedOperations = new HashMap<>(operationInfo.length); + this.allowedOperations = CollectionUtils.newHashMap(operationInfo.length); for (MBeanOperationInfo infoEle : operationInfo) { Class[] paramTypes = JmxUtils.parameterInfoToTypes(infoEle.getSignature(), this.beanClassLoader); this.allowedOperations.put(new MethodCacheKey(infoEle.getName(), paramTypes), infoEle); diff --git a/spring-context/src/main/java/org/springframework/jmx/export/assembler/InterfaceBasedMBeanInfoAssembler.java b/spring-context/src/main/java/org/springframework/jmx/export/assembler/InterfaceBasedMBeanInfoAssembler.java index 72bbaa3242..4be4b5e050 100644 --- a/spring-context/src/main/java/org/springframework/jmx/export/assembler/InterfaceBasedMBeanInfoAssembler.java +++ b/spring-context/src/main/java/org/springframework/jmx/export/assembler/InterfaceBasedMBeanInfoAssembler.java @@ -20,7 +20,6 @@ import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.util.Arrays; import java.util.Enumeration; -import java.util.HashMap; import java.util.Map; import java.util.Properties; @@ -28,6 +27,7 @@ import org.springframework.beans.factory.BeanClassLoaderAware; import org.springframework.beans.factory.InitializingBean; import org.springframework.lang.Nullable; import org.springframework.util.ClassUtils; +import org.springframework.util.CollectionUtils; import org.springframework.util.StringUtils; /** @@ -126,7 +126,7 @@ public class InterfaceBasedMBeanInfoAssembler extends AbstractConfigurableMBeanI * @return the resolved interface mappings (with Class objects as values) */ private Map[]> resolveInterfaceMappings(Properties mappings) { - Map[]> resolvedMappings = new HashMap<>(mappings.size()); + Map[]> resolvedMappings = CollectionUtils.newHashMap(mappings.size()); for (Enumeration en = mappings.propertyNames(); en.hasMoreElements();) { String beanKey = (String) en.nextElement(); String[] classNames = StringUtils.commaDelimitedListToStringArray(mappings.getProperty(beanKey)); diff --git a/spring-core/src/jmh/java/org/springframework/core/convert/support/GenericConversionServiceBenchmark.java b/spring-core/src/jmh/java/org/springframework/core/convert/support/GenericConversionServiceBenchmark.java index 8cd4ba48fc..b31e69d5be 100644 --- a/spring-core/src/jmh/java/org/springframework/core/convert/support/GenericConversionServiceBenchmark.java +++ b/spring-core/src/jmh/java/org/springframework/core/convert/support/GenericConversionServiceBenchmark.java @@ -34,9 +34,11 @@ import org.openjdk.jmh.annotations.State; import org.openjdk.jmh.infra.Blackhole; import org.springframework.core.convert.TypeDescriptor; +import org.springframework.util.CollectionUtils; /** * Benchmarks for {@link GenericConversionService}. + * * @author Brian Clozel */ @BenchmarkMode(Mode.Throughput) @@ -78,11 +80,12 @@ public class GenericConversionServiceBenchmark { @Benchmark public void convertMapOfStringToListOfIntegerBaseline(MapBenchmarkState state, Blackhole bh) { - Map target = new HashMap<>(state.source.size()); + Map target = CollectionUtils.newHashMap(state.source.size()); state.source.forEach((k, v) -> target.put(k, Integer.valueOf(v))); bh.consume(target); } + @State(Scope.Benchmark) public static class MapBenchmarkState extends BenchmarkState { @@ -90,7 +93,7 @@ public class GenericConversionServiceBenchmark { @Setup(Level.Trial) public void setup() throws Exception { - this.source = new HashMap<>(this.collectionSize); + this.source = CollectionUtils.newHashMap(this.collectionSize); Map target = new HashMap<>(); this.targetTypeDesc = TypeDescriptor.forObject(target); this.source = IntStream.rangeClosed(1, collectionSize).mapToObj(String::valueOf) @@ -98,6 +101,7 @@ public class GenericConversionServiceBenchmark { } } + @State(Scope.Benchmark) public static class BenchmarkState { @@ -107,6 +111,6 @@ public class GenericConversionServiceBenchmark { int collectionSize; TypeDescriptor targetTypeDesc; - } + } diff --git a/spring-core/src/main/java/org/springframework/core/annotation/AnnotationUtils.java b/spring-core/src/main/java/org/springframework/core/annotation/AnnotationUtils.java index b7f7f959fd..edd0996241 100644 --- a/spring-core/src/main/java/org/springframework/core/annotation/AnnotationUtils.java +++ b/spring-core/src/main/java/org/springframework/core/annotation/AnnotationUtils.java @@ -24,7 +24,6 @@ import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.util.Collection; import java.util.Collections; -import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.NoSuchElementException; @@ -35,6 +34,7 @@ import org.springframework.core.annotation.AnnotationTypeMapping.MirrorSets.Mirr import org.springframework.core.annotation.MergedAnnotation.Adapt; import org.springframework.core.annotation.MergedAnnotations.SearchStrategy; import org.springframework.lang.Nullable; +import org.springframework.util.CollectionUtils; import org.springframework.util.ConcurrentReferenceHashMap; import org.springframework.util.ReflectionUtils; import org.springframework.util.StringUtils; @@ -905,7 +905,7 @@ public abstract class AnnotationUtils { if (!methods.hasDefaultValueMethod()) { return Collections.emptyMap(); } - Map result = new LinkedHashMap<>(methods.size()); + Map result = CollectionUtils.newLinkedHashMap(methods.size()); if (!methods.hasNestedAnnotation()) { // Use simpler method if there are no nested annotations for (int i = 0; i < methods.size(); i++) { diff --git a/spring-core/src/main/java/org/springframework/core/codec/Hints.java b/spring-core/src/main/java/org/springframework/core/codec/Hints.java index 5b1610cabc..7f167fd509 100644 --- a/spring-core/src/main/java/org/springframework/core/codec/Hints.java +++ b/spring-core/src/main/java/org/springframework/core/codec/Hints.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2020 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. @@ -17,12 +17,12 @@ package org.springframework.core.codec; import java.util.Collections; -import java.util.HashMap; import java.util.Map; import org.apache.commons.logging.Log; import org.springframework.lang.Nullable; +import org.springframework.util.CollectionUtils; /** * Constants and convenience methods for working with hints. @@ -120,7 +120,7 @@ public abstract class Hints { return hints2; } else { - Map result = new HashMap<>(hints1.size() + hints2.size()); + Map result = CollectionUtils.newHashMap(hints1.size() + hints2.size()); result.putAll(hints1); result.putAll(hints2); return result; @@ -141,7 +141,7 @@ public abstract class Hints { return Collections.singletonMap(hintName, hintValue); } else { - Map result = new HashMap<>(hints.size() + 1); + Map result = CollectionUtils.newHashMap(hints.size() + 1); result.putAll(hints); result.put(hintName, hintValue); return result; diff --git a/spring-core/src/main/java/org/springframework/core/type/classreading/AnnotationMetadataReadingVisitor.java b/spring-core/src/main/java/org/springframework/core/type/classreading/AnnotationMetadataReadingVisitor.java index 5ca315cf07..9435af78ed 100644 --- a/spring-core/src/main/java/org/springframework/core/type/classreading/AnnotationMetadataReadingVisitor.java +++ b/spring-core/src/main/java/org/springframework/core/type/classreading/AnnotationMetadataReadingVisitor.java @@ -68,7 +68,7 @@ public class AnnotationMetadataReadingVisitor extends ClassMetadataReadingVisito * to ensure that the hierarchical ordering of the entries is preserved. * @see AnnotationReadingVisitorUtils#getMergedAnnotationAttributes */ - protected final LinkedMultiValueMap attributesMap = new LinkedMultiValueMap<>(4); + protected final LinkedMultiValueMap attributesMap = new LinkedMultiValueMap<>(3); protected final Set methodMetadataSet = new LinkedHashSet<>(4); diff --git a/spring-core/src/main/java/org/springframework/core/type/classreading/MethodMetadataReadingVisitor.java b/spring-core/src/main/java/org/springframework/core/type/classreading/MethodMetadataReadingVisitor.java index 034e571814..f352428b33 100644 --- a/spring-core/src/main/java/org/springframework/core/type/classreading/MethodMetadataReadingVisitor.java +++ b/spring-core/src/main/java/org/springframework/core/type/classreading/MethodMetadataReadingVisitor.java @@ -66,7 +66,7 @@ public class MethodMetadataReadingVisitor extends MethodVisitor implements Metho protected final Map> metaAnnotationMap = new LinkedHashMap<>(4); - protected final LinkedMultiValueMap attributesMap = new LinkedMultiValueMap<>(4); + protected final LinkedMultiValueMap attributesMap = new LinkedMultiValueMap<>(3); public MethodMetadataReadingVisitor(String methodName, int access, String declaringClassName, diff --git a/spring-core/src/main/java/org/springframework/util/CollectionUtils.java b/spring-core/src/main/java/org/springframework/util/CollectionUtils.java index 1ec0510467..6ae36be038 100644 --- a/spring-core/src/main/java/org/springframework/util/CollectionUtils.java +++ b/spring-core/src/main/java/org/springframework/util/CollectionUtils.java @@ -21,6 +21,7 @@ import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.Enumeration; +import java.util.HashMap; import java.util.Iterator; import java.util.LinkedHashMap; import java.util.List; @@ -42,6 +43,14 @@ import org.springframework.lang.Nullable; */ public abstract class CollectionUtils { + /** + * Default load factor for {@link HashMap}/{@link LinkedHashMap} variants. + * @see #newHashMap(int) + * @see #newLinkedHashMap(int) + */ + static final float DEFAULT_LOAD_FACTOR = 0.75f; + + /** * Return {@code true} if the supplied Collection is {@code null} or empty. * Otherwise, return {@code false}. @@ -62,6 +71,37 @@ public abstract class CollectionUtils { return (map == null || map.isEmpty()); } + /** + * Instantiate a new {@link HashMap} with an initial capacity + * that can accommodate the given number of elements. + *

This differs from the regular {@link HashMap} constructor + * which takes an initial capacity relative to a load factor + * but is effectively aligned with the JDK's + * {@link java.util.concurrent.ConcurrentHashMap#ConcurrentHashMap(int)}. + * @param expectedSize the expected number of elements + * @since 5.3 + * @see #newLinkedHashMap(int) + */ + @SuppressWarnings({"rawtypes", "unchecked"}) + public static HashMap newHashMap(int expectedSize) { + return new HashMap((int) (expectedSize / DEFAULT_LOAD_FACTOR), DEFAULT_LOAD_FACTOR); + } + + /** + * Instantiate a new {@link LinkedHashMap} with an initial capacity + * that can accommodate the given number of elements. + *

This differs from the regular {@link LinkedHashMap} constructor + * which takes an initial capacity relative to a load factor but is + * aligned with Spring's own {@link LinkedCaseInsensitiveMap} and + * {@link LinkedMultiValueMap} constructor semantics as of 5.3. + * @param expectedSize the expected number of elements + * @since 5.3 + */ + @SuppressWarnings({"rawtypes", "unchecked"}) + public static LinkedHashMap newLinkedHashMap(int expectedSize) { + return new LinkedHashMap((int) (expectedSize / DEFAULT_LOAD_FACTOR), DEFAULT_LOAD_FACTOR); + } + /** * Convert the supplied array into a List. A primitive array gets converted * into a List of the appropriate wrapper type. @@ -74,8 +114,7 @@ public abstract class CollectionUtils { * @see ObjectUtils#toObjectArray(Object) * @see Arrays#asList(Object[]) */ - @SuppressWarnings("rawtypes") - public static List arrayToList(@Nullable Object source) { + public static List arrayToList(@Nullable Object source) { return Arrays.asList(ObjectUtils.toObjectArray(source)); } @@ -430,7 +469,7 @@ public abstract class CollectionUtils { MultiValueMap targetMap) { Assert.notNull(targetMap, "'targetMap' must not be null"); - Map> result = new LinkedHashMap<>(targetMap.size()); + Map> result = newLinkedHashMap(targetMap.size()); targetMap.forEach((key, value) -> { List values = Collections.unmodifiableList(value); result.put(key, (List) values); diff --git a/spring-core/src/main/java/org/springframework/util/LinkedCaseInsensitiveMap.java b/spring-core/src/main/java/org/springframework/util/LinkedCaseInsensitiveMap.java index a7e24a7620..b7c6ab5d5f 100644 --- a/spring-core/src/main/java/org/springframework/util/LinkedCaseInsensitiveMap.java +++ b/spring-core/src/main/java/org/springframework/util/LinkedCaseInsensitiveMap.java @@ -76,7 +76,7 @@ public class LinkedCaseInsensitiveMap implements Map, Serializable /** * Create a new LinkedCaseInsensitiveMap that stores case-insensitive keys - * according to the given Locale (by default in lower case). + * according to the given Locale (in lower case). * @param locale the Locale to use for case-insensitive key conversion * @see #convertKey(String) */ @@ -86,25 +86,26 @@ public class LinkedCaseInsensitiveMap implements Map, Serializable /** * Create a new LinkedCaseInsensitiveMap that wraps a {@link LinkedHashMap} - * with the given initial capacity and stores case-insensitive keys - * according to the default Locale (by default in lower case). - * @param initialCapacity the initial capacity + * with an initial capacity that can accommodate the given number of elements, + * storing case-insensitive keys according to the default Locale (in lower case). + * @param expectedSize the expected number of elements * @see #convertKey(String) */ - public LinkedCaseInsensitiveMap(int initialCapacity) { - this(initialCapacity, null); + public LinkedCaseInsensitiveMap(int expectedSize) { + this(expectedSize, null); } /** * Create a new LinkedCaseInsensitiveMap that wraps a {@link LinkedHashMap} - * with the given initial capacity and stores case-insensitive keys - * according to the given Locale (by default in lower case). - * @param initialCapacity the initial capacity + * with an initial capacity that can accommodate the given number of elements, + * storing case-insensitive keys according to the given Locale (in lower case). + * @param expectedSize the expected number of elements * @param locale the Locale to use for case-insensitive key conversion * @see #convertKey(String) */ - public LinkedCaseInsensitiveMap(int initialCapacity, @Nullable Locale locale) { - this.targetMap = new LinkedHashMap(initialCapacity) { + public LinkedCaseInsensitiveMap(int expectedSize, @Nullable Locale locale) { + this.targetMap = new LinkedHashMap( + (int) (expectedSize / CollectionUtils.DEFAULT_LOAD_FACTOR), CollectionUtils.DEFAULT_LOAD_FACTOR) { @Override public boolean containsKey(Object key) { return LinkedCaseInsensitiveMap.this.containsKey(key); @@ -118,7 +119,7 @@ public class LinkedCaseInsensitiveMap implements Map, Serializable return doRemove; } }; - this.caseInsensitiveKeys = new HashMap<>(initialCapacity); + this.caseInsensitiveKeys = CollectionUtils.newHashMap(expectedSize); this.locale = (locale != null ? locale : Locale.getDefault()); } diff --git a/spring-core/src/main/java/org/springframework/util/LinkedMultiValueMap.java b/spring-core/src/main/java/org/springframework/util/LinkedMultiValueMap.java index 00ef6b4d6b..141b022364 100644 --- a/spring-core/src/main/java/org/springframework/util/LinkedMultiValueMap.java +++ b/spring-core/src/main/java/org/springframework/util/LinkedMultiValueMap.java @@ -49,11 +49,11 @@ public class LinkedMultiValueMap extends MultiValueMapAdapter implem /** * Create a new LinkedMultiValueMap that wraps a {@link LinkedHashMap} - * with the given initial capacity. - * @param initialCapacity the initial capacity + * with an initial capacity that can accommodate the given number of elements. + * @param expectedSize the expected number of elements */ - public LinkedMultiValueMap(int initialCapacity) { - super(new LinkedHashMap<>(initialCapacity)); + public LinkedMultiValueMap(int expectedSize) { + super(CollectionUtils.newLinkedHashMap(expectedSize)); } /** diff --git a/spring-core/src/main/java/org/springframework/util/MultiValueMapAdapter.java b/spring-core/src/main/java/org/springframework/util/MultiValueMapAdapter.java index cfbf79cb3b..88611dbe27 100644 --- a/spring-core/src/main/java/org/springframework/util/MultiValueMapAdapter.java +++ b/spring-core/src/main/java/org/springframework/util/MultiValueMapAdapter.java @@ -18,7 +18,6 @@ package org.springframework.util; import java.io.Serializable; import java.util.Collection; -import java.util.LinkedHashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; @@ -88,7 +87,7 @@ class MultiValueMapAdapter implements MultiValueMap, Serializable { @Override public Map toSingleValueMap() { - Map singleValueMap = new LinkedHashMap<>(this.targetMap.size()); + Map singleValueMap = CollectionUtils.newLinkedHashMap(this.targetMap.size()); this.targetMap.forEach((key, values) -> { if (values != null && !values.isEmpty()) { singleValueMap.put(key, values.get(0)); diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/core/JdbcTemplate.java b/spring-jdbc/src/main/java/org/springframework/jdbc/core/JdbcTemplate.java index 53b3b9eff5..f41390c2c4 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/core/JdbcTemplate.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/core/JdbcTemplate.java @@ -55,6 +55,7 @@ import org.springframework.jdbc.support.KeyHolder; import org.springframework.jdbc.support.rowset.SqlRowSet; import org.springframework.lang.Nullable; import org.springframework.util.Assert; +import org.springframework.util.CollectionUtils; import org.springframework.util.LinkedCaseInsensitiveMap; import org.springframework.util.StringUtils; @@ -1333,7 +1334,7 @@ public class JdbcTemplate extends JdbcAccessor implements JdbcOperations { protected Map extractOutputParameters(CallableStatement cs, List parameters) throws SQLException { - Map results = new LinkedHashMap<>(parameters.size()); + Map results = CollectionUtils.newLinkedHashMap(parameters.size()); int sqlColIndex = 1; for (SqlParameter param : parameters) { if (param instanceof SqlOutParameter) { diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/core/metadata/CallMetaDataContext.java b/spring-jdbc/src/main/java/org/springframework/jdbc/core/metadata/CallMetaDataContext.java index b707d6d315..ae80a8eb91 100755 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/core/metadata/CallMetaDataContext.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/core/metadata/CallMetaDataContext.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2020 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. @@ -18,7 +18,6 @@ package org.springframework.jdbc.core.metadata; import java.sql.DatabaseMetaData; import java.util.ArrayList; -import java.util.HashMap; import java.util.HashSet; import java.util.LinkedHashMap; import java.util.List; @@ -42,6 +41,7 @@ import org.springframework.jdbc.core.namedparam.SqlParameterSourceUtils; import org.springframework.jdbc.support.JdbcUtils; import org.springframework.lang.Nullable; import org.springframework.util.Assert; +import org.springframework.util.CollectionUtils; import org.springframework.util.StringUtils; /** @@ -369,7 +369,7 @@ public class CallMetaDataContext { return workParams; } - Map limitedInParamNamesMap = new HashMap<>(this.limitedInParameterNames.size()); + Map limitedInParamNamesMap = CollectionUtils.newHashMap(this.limitedInParameterNames.size()); for (String limitedParamName : this.limitedInParameterNames) { limitedInParamNamesMap.put(lowerCase(provider.parameterNameToUse(limitedParamName)), limitedParamName); } @@ -482,8 +482,8 @@ public class CallMetaDataContext { Map caseInsensitiveParameterNames = SqlParameterSourceUtils.extractCaseInsensitiveParameterNames(parameterSource); - Map callParameterNames = new HashMap<>(this.callParameters.size()); - Map matchedParameters = new HashMap<>(this.callParameters.size()); + Map callParameterNames = CollectionUtils.newHashMap(this.callParameters.size()); + Map matchedParameters = CollectionUtils.newHashMap(this.callParameters.size()); for (SqlParameter parameter : this.callParameters) { if (parameter.isInputValueProvided()) { String parameterName = parameter.getName(); @@ -551,7 +551,7 @@ public class CallMetaDataContext { return inParameters; } - Map callParameterNames = new HashMap<>(this.callParameters.size()); + Map callParameterNames = CollectionUtils.newHashMap(this.callParameters.size()); for (SqlParameter parameter : this.callParameters) { if (parameter.isInputValueProvided()) { String parameterName = parameter.getName(); @@ -562,7 +562,7 @@ public class CallMetaDataContext { } } - Map matchedParameters = new HashMap<>(inParameters.size()); + Map matchedParameters = CollectionUtils.newHashMap(inParameters.size()); inParameters.forEach((parameterName, parameterValue) -> { String parameterNameToMatch = provider.parameterNameToUse(parameterName); String callParameterName = callParameterNames.get(lowerCase(parameterNameToMatch)); @@ -602,7 +602,7 @@ public class CallMetaDataContext { } public Map matchInParameterValuesWithCallParameters(Object[] parameterValues) { - Map matchedParameters = new HashMap<>(parameterValues.length); + Map matchedParameters = CollectionUtils.newHashMap(parameterValues.length); int i = 0; for (SqlParameter parameter : this.callParameters) { if (parameter.isInputValueProvided()) { diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/core/metadata/TableMetaDataContext.java b/spring-jdbc/src/main/java/org/springframework/jdbc/core/metadata/TableMetaDataContext.java index ca57f52874..908b165bef 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/core/metadata/TableMetaDataContext.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/core/metadata/TableMetaDataContext.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2020 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. @@ -18,7 +18,6 @@ package org.springframework.jdbc.core.metadata; import java.util.ArrayList; import java.util.Collections; -import java.util.LinkedHashMap; import java.util.LinkedHashSet; import java.util.List; import java.util.Map; @@ -36,6 +35,7 @@ import org.springframework.jdbc.core.namedparam.SqlParameterSourceUtils; import org.springframework.jdbc.support.JdbcUtils; import org.springframework.lang.Nullable; import org.springframework.util.Assert; +import org.springframework.util.CollectionUtils; /** * Class to manage context meta-data used for the configuration @@ -319,7 +319,7 @@ public class TableMetaDataContext { public int[] createInsertTypes() { int[] types = new int[getTableColumns().size()]; List parameters = obtainMetaDataProvider().getTableParameterMetaData(); - Map parameterMap = new LinkedHashMap<>(parameters.size()); + Map parameterMap = CollectionUtils.newLinkedHashMap(parameters.size()); for (TableParameterMetaData tpmd : parameters) { parameterMap.put(tpmd.getParameterName().toUpperCase(), tpmd); } diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/lookup/AbstractRoutingDataSource.java b/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/lookup/AbstractRoutingDataSource.java index 88669594b1..ec33aba101 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/lookup/AbstractRoutingDataSource.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/lookup/AbstractRoutingDataSource.java @@ -19,7 +19,6 @@ package org.springframework.jdbc.datasource.lookup; import java.sql.Connection; import java.sql.SQLException; import java.util.Collections; -import java.util.HashMap; import java.util.Map; import javax.sql.DataSource; @@ -28,6 +27,7 @@ import org.springframework.beans.factory.InitializingBean; import org.springframework.jdbc.datasource.AbstractDataSource; import org.springframework.lang.Nullable; import org.springframework.util.Assert; +import org.springframework.util.CollectionUtils; /** * Abstract {@link javax.sql.DataSource} implementation that routes {@link #getConnection()} @@ -119,7 +119,7 @@ public abstract class AbstractRoutingDataSource extends AbstractDataSource imple if (this.targetDataSources == null) { throw new IllegalArgumentException("Property 'targetDataSources' is required"); } - this.resolvedDataSources = new HashMap<>(this.targetDataSources.size()); + this.resolvedDataSources = CollectionUtils.newHashMap(this.targetDataSources.size()); this.targetDataSources.forEach((key, value) -> { Object lookupKey = resolveSpecifiedLookupKey(key); DataSource dataSource = resolveSpecifiedDataSource(value); diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/support/rowset/ResultSetWrappingSqlRowSet.java b/spring-jdbc/src/main/java/org/springframework/jdbc/support/rowset/ResultSetWrappingSqlRowSet.java index 220c8d1746..c399afa961 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/support/rowset/ResultSetWrappingSqlRowSet.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/support/rowset/ResultSetWrappingSqlRowSet.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2020 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. @@ -25,11 +25,11 @@ import java.sql.Time; import java.sql.Timestamp; import java.util.Calendar; import java.util.Collections; -import java.util.HashMap; import java.util.Map; import org.springframework.jdbc.InvalidResultSetAccessException; import org.springframework.lang.Nullable; +import org.springframework.util.CollectionUtils; /** * The default implementation of Spring's {@link SqlRowSet} interface, wrapping a @@ -97,7 +97,7 @@ public class ResultSetWrappingSqlRowSet implements SqlRowSet { ResultSetMetaData rsmd = resultSet.getMetaData(); if (rsmd != null) { int columnCount = rsmd.getColumnCount(); - this.columnLabelMap = new HashMap<>(columnCount); + this.columnLabelMap = CollectionUtils.newHashMap(columnCount); for (int i = 1; i <= columnCount; i++) { String key = rsmd.getColumnLabel(i); // Make sure to preserve first matching column for any given name, 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 9f98ebfc71..8fd2b3f94a 100644 --- a/spring-messaging/src/main/java/org/springframework/messaging/MessageHeaders.java +++ b/spring-messaging/src/main/java/org/springframework/messaging/MessageHeaders.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2020 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. @@ -33,6 +33,7 @@ import org.apache.commons.logging.LogFactory; import org.springframework.lang.Nullable; import org.springframework.util.AlternativeJdkIdGenerator; +import org.springframework.util.CollectionUtils; import org.springframework.util.IdGenerator; /** @@ -164,7 +165,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()); + this.headers = CollectionUtils.newHashMap(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/handler/invocation/AbstractMethodMessageHandler.java b/spring-messaging/src/main/java/org/springframework/messaging/handler/invocation/AbstractMethodMessageHandler.java index 67aa3da79a..fc50155039 100644 --- a/spring-messaging/src/main/java/org/springframework/messaging/handler/invocation/AbstractMethodMessageHandler.java +++ b/spring-messaging/src/main/java/org/springframework/messaging/handler/invocation/AbstractMethodMessageHandler.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2020 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. @@ -109,7 +109,7 @@ public abstract class AbstractMethodMessageHandler private final Map handlerMethods = new LinkedHashMap<>(64); - private final MultiValueMap destinationLookup = new LinkedMultiValueMap<>(64); + private final MultiValueMap destinationLookup = new LinkedMultiValueMap<>(48); private final Map, AbstractExceptionHandlerMethodResolver> exceptionHandlerCache = new ConcurrentHashMap<>(64); diff --git a/spring-messaging/src/main/java/org/springframework/messaging/handler/invocation/reactive/AbstractMethodMessageHandler.java b/spring-messaging/src/main/java/org/springframework/messaging/handler/invocation/reactive/AbstractMethodMessageHandler.java index 210175caee..c193249c60 100644 --- a/spring-messaging/src/main/java/org/springframework/messaging/handler/invocation/reactive/AbstractMethodMessageHandler.java +++ b/spring-messaging/src/main/java/org/springframework/messaging/handler/invocation/reactive/AbstractMethodMessageHandler.java @@ -106,7 +106,7 @@ public abstract class AbstractMethodMessageHandler private final Map handlerMethods = new LinkedHashMap<>(64); - private final MultiValueMap destinationLookup = new LinkedMultiValueMap<>(64); + private final MultiValueMap destinationLookup = new LinkedMultiValueMap<>(48); /** diff --git a/spring-messaging/src/main/java/org/springframework/messaging/rsocket/annotation/support/RSocketFrameTypeMessageCondition.java b/spring-messaging/src/main/java/org/springframework/messaging/rsocket/annotation/support/RSocketFrameTypeMessageCondition.java index 7ae1c1bf9c..b361593781 100644 --- a/spring-messaging/src/main/java/org/springframework/messaging/rsocket/annotation/support/RSocketFrameTypeMessageCondition.java +++ b/spring-messaging/src/main/java/org/springframework/messaging/rsocket/annotation/support/RSocketFrameTypeMessageCondition.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2020 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. @@ -18,7 +18,6 @@ package org.springframework.messaging.rsocket.annotation.support; import java.util.Arrays; import java.util.Collection; import java.util.Collections; -import java.util.HashMap; import java.util.LinkedHashSet; import java.util.Map; import java.util.Set; @@ -29,6 +28,7 @@ import org.springframework.lang.Nullable; import org.springframework.messaging.Message; import org.springframework.messaging.handler.AbstractMessageCondition; import org.springframework.util.Assert; +import org.springframework.util.CollectionUtils; /** * A condition to assist with mapping onto handler methods based on the RSocket @@ -88,7 +88,7 @@ public class RSocketFrameTypeMessageCondition extends AbstractMessageCondition frameTypeConditionCache; static { - frameTypeConditionCache = new HashMap<>(FrameType.values().length); + frameTypeConditionCache = CollectionUtils.newHashMap(FrameType.values().length); for (FrameType type : FrameType.values()) { frameTypeConditionCache.put(type.name(), new RSocketFrameTypeMessageCondition(type)); } diff --git a/spring-messaging/src/main/java/org/springframework/messaging/simp/stomp/StompHeaders.java b/spring-messaging/src/main/java/org/springframework/messaging/simp/stomp/StompHeaders.java index aee747f710..2e84545a3d 100644 --- a/spring-messaging/src/main/java/org/springframework/messaging/simp/stomp/StompHeaders.java +++ b/spring-messaging/src/main/java/org/springframework/messaging/simp/stomp/StompHeaders.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2020 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. @@ -28,6 +28,7 @@ import java.util.Set; import org.springframework.lang.Nullable; import org.springframework.util.Assert; +import org.springframework.util.CollectionUtils; import org.springframework.util.LinkedMultiValueMap; import org.springframework.util.MimeType; import org.springframework.util.MimeTypeUtils; @@ -110,7 +111,7 @@ public class StompHeaders implements MultiValueMap, Serializable * Create a new instance to be populated with new header values. */ public StompHeaders() { - this(new LinkedMultiValueMap<>(4), false); + this(new LinkedMultiValueMap<>(3), false); } private StompHeaders(Map> headers, boolean readOnly) { @@ -482,7 +483,7 @@ public class StompHeaders implements MultiValueMap, Serializable @Override public Map toSingleValueMap() { - LinkedHashMap singleValueMap = new LinkedHashMap<>(this.headers.size()); + LinkedHashMap singleValueMap = CollectionUtils.newLinkedHashMap(this.headers.size()); this.headers.forEach((key, value) -> singleValueMap.put(key, value.get(0))); return singleValueMap; } 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 cd91ab3b54..b77893879e 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 @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2020 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. @@ -33,6 +33,7 @@ import org.springframework.lang.Nullable; import org.springframework.messaging.Message; import org.springframework.messaging.converter.MessageConverter; import org.springframework.util.Assert; +import org.springframework.util.CollectionUtils; import org.springframework.util.ObjectUtils; /** @@ -209,7 +210,7 @@ public class MultiServerUserRegistry implements SimpUserRegistry, SmartApplicati public UserRegistrySnapshot(String id, SimpUserRegistry registry) { this.id = id; Set users = registry.getUsers(); - this.users = new HashMap<>(users.size()); + this.users = CollectionUtils.newHashMap(users.size()); for (SimpUser user : users) { this.users.put(user.getName(), new TransferSimpUser(user)); } diff --git a/spring-messaging/src/main/java/org/springframework/messaging/support/NativeMessageHeaderAccessor.java b/spring-messaging/src/main/java/org/springframework/messaging/support/NativeMessageHeaderAccessor.java index 624f0964d8..4243f78c5e 100644 --- a/spring-messaging/src/main/java/org/springframework/messaging/support/NativeMessageHeaderAccessor.java +++ b/spring-messaging/src/main/java/org/springframework/messaging/support/NativeMessageHeaderAccessor.java @@ -163,7 +163,7 @@ public class NativeMessageHeaderAccessor extends MessageHeaderAccessor { return; } if (map == null) { - map = new LinkedMultiValueMap<>(4); + map = new LinkedMultiValueMap<>(3); setHeader(NATIVE_HEADERS, map); } List values = new LinkedList<>(); @@ -184,7 +184,7 @@ public class NativeMessageHeaderAccessor extends MessageHeaderAccessor { } Map> nativeHeaders = getNativeHeaders(); if (nativeHeaders == null) { - nativeHeaders = new LinkedMultiValueMap<>(4); + nativeHeaders = new LinkedMultiValueMap<>(3); setHeader(NATIVE_HEADERS, nativeHeaders); } List values = nativeHeaders.computeIfAbsent(name, k -> new LinkedList<>()); diff --git a/spring-oxm/src/main/java/org/springframework/oxm/xstream/XStreamMarshaller.java b/spring-oxm/src/main/java/org/springframework/oxm/xstream/XStreamMarshaller.java index 090ae9f167..c96998d531 100644 --- a/spring-oxm/src/main/java/org/springframework/oxm/xstream/XStreamMarshaller.java +++ b/spring-oxm/src/main/java/org/springframework/oxm/xstream/XStreamMarshaller.java @@ -24,7 +24,6 @@ import java.io.OutputStreamWriter; import java.io.Reader; import java.io.Writer; import java.lang.reflect.Constructor; -import java.util.LinkedHashMap; import java.util.List; import java.util.Map; @@ -82,6 +81,7 @@ import org.springframework.oxm.UnmarshallingFailureException; import org.springframework.oxm.XmlMappingException; import org.springframework.oxm.support.AbstractMarshaller; import org.springframework.util.ClassUtils; +import org.springframework.util.CollectionUtils; import org.springframework.util.ObjectUtils; import org.springframework.util.StringUtils; import org.springframework.util.function.SingletonSupplier; @@ -584,7 +584,7 @@ public class XStreamMarshaller extends AbstractMarshaller implements BeanClassLo } private Map> toClassMap(Map map) throws ClassNotFoundException { - Map> result = new LinkedHashMap<>(map.size()); + Map> result = CollectionUtils.newLinkedHashMap(map.size()); for (Map.Entry entry : map.entrySet()) { String key = entry.getKey(); Object value = entry.getValue(); diff --git a/spring-r2dbc/src/main/java/org/springframework/r2dbc/connection/lookup/AbstractRoutingConnectionFactory.java b/spring-r2dbc/src/main/java/org/springframework/r2dbc/connection/lookup/AbstractRoutingConnectionFactory.java index 2649e179b9..ace6c52976 100644 --- a/spring-r2dbc/src/main/java/org/springframework/r2dbc/connection/lookup/AbstractRoutingConnectionFactory.java +++ b/spring-r2dbc/src/main/java/org/springframework/r2dbc/connection/lookup/AbstractRoutingConnectionFactory.java @@ -16,7 +16,6 @@ package org.springframework.r2dbc.connection.lookup; -import java.util.HashMap; import java.util.Map; import io.r2dbc.spi.Connection; @@ -27,6 +26,7 @@ import reactor.core.publisher.Mono; import org.springframework.beans.factory.InitializingBean; import org.springframework.lang.Nullable; import org.springframework.util.Assert; +import org.springframework.util.CollectionUtils; /** * Abstract {@link ConnectionFactory} implementation that routes @@ -129,12 +129,12 @@ public abstract class AbstractRoutingConnectionFactory implements ConnectionFact this.connectionFactoryLookup = connectionFactoryLookup; } + @Override public void afterPropertiesSet() { - Assert.notNull(this.targetConnectionFactories, "Property 'targetConnectionFactories' must not be null"); - this.resolvedConnectionFactories = new HashMap<>(this.targetConnectionFactories.size()); + this.resolvedConnectionFactories = CollectionUtils.newHashMap(this.targetConnectionFactories.size()); this.targetConnectionFactories.forEach((key, value) -> { Object lookupKey = resolveSpecifiedLookupKey(key); ConnectionFactory connectionFactory = resolveSpecifiedConnectionFactory(value); diff --git a/spring-r2dbc/src/main/java/org/springframework/r2dbc/core/DefaultDatabaseClient.java b/spring-r2dbc/src/main/java/org/springframework/r2dbc/core/DefaultDatabaseClient.java index 8663ef7309..c0d1a7a226 100644 --- a/spring-r2dbc/src/main/java/org/springframework/r2dbc/core/DefaultDatabaseClient.java +++ b/spring-r2dbc/src/main/java/org/springframework/r2dbc/core/DefaultDatabaseClient.java @@ -51,6 +51,7 @@ import org.springframework.r2dbc.connection.ConnectionFactoryUtils; import org.springframework.r2dbc.core.binding.BindMarkersFactory; import org.springframework.r2dbc.core.binding.BindTarget; import org.springframework.util.Assert; +import org.springframework.util.CollectionUtils; import org.springframework.util.StringUtils; /** @@ -255,7 +256,6 @@ class DefaultDatabaseClient implements DatabaseClient { "Value at index %d must not be null. Use bindNull(…) instead.", index)); Map byIndex = new LinkedHashMap<>(this.byIndex); - if (value instanceof Parameter) { byIndex.put(index, (Parameter) value); } @@ -285,7 +285,6 @@ class DefaultDatabaseClient implements DatabaseClient { "Value for parameter %s must not be null. Use bindNull(…) instead.", name)); Map byName = new LinkedHashMap<>(this.byName); - if (value instanceof Parameter) { byName.put(name, (Parameter) value); } @@ -393,7 +392,7 @@ class DefaultDatabaseClient implements DatabaseClient { private MapBindParameterSource retrieveParameters(String sql, List parameterNames, Map remainderByName, Map remainderByIndex) { - Map namedBindings = new LinkedHashMap<>(parameterNames.size()); + Map namedBindings = CollectionUtils.newLinkedHashMap(parameterNames.size()); for (String parameterName : parameterNames) { Parameter parameter = getParameter(remainderByName, remainderByIndex, parameterNames, parameterName); if (parameter == null) { diff --git a/spring-r2dbc/src/main/java/org/springframework/r2dbc/core/binding/Bindings.java b/spring-r2dbc/src/main/java/org/springframework/r2dbc/core/binding/Bindings.java index 7e851d2020..34bfae03b8 100644 --- a/spring-r2dbc/src/main/java/org/springframework/r2dbc/core/binding/Bindings.java +++ b/spring-r2dbc/src/main/java/org/springframework/r2dbc/core/binding/Bindings.java @@ -20,7 +20,6 @@ import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.Iterator; -import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Spliterator; @@ -31,6 +30,7 @@ import io.r2dbc.spi.Statement; import org.springframework.lang.NonNull; import org.springframework.lang.Nullable; import org.springframework.util.Assert; +import org.springframework.util.CollectionUtils; /** * Value object representing value and {@code null} bindings @@ -60,7 +60,7 @@ public class Bindings implements Iterable { */ public Bindings(Collection bindings) { Assert.notNull(bindings, "Bindings must not be null"); - Map mapping = new LinkedHashMap<>(bindings.size()); + Map mapping = CollectionUtils.newLinkedHashMap(bindings.size()); bindings.forEach(binding -> mapping.put(binding.getBindMarker(), binding)); this.bindings = mapping; } diff --git a/spring-web/src/main/java/org/springframework/http/client/reactive/HttpComponentsHeadersAdapter.java b/spring-web/src/main/java/org/springframework/http/client/reactive/HttpComponentsHeadersAdapter.java index 7880f6e0e4..f24d77cb86 100644 --- a/spring-web/src/main/java/org/springframework/http/client/reactive/HttpComponentsHeadersAdapter.java +++ b/spring-web/src/main/java/org/springframework/http/client/reactive/HttpComponentsHeadersAdapter.java @@ -22,7 +22,6 @@ import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.Iterator; -import java.util.LinkedHashMap; import java.util.LinkedHashSet; import java.util.List; import java.util.Map; @@ -33,6 +32,7 @@ import org.apache.hc.core5.http.HttpResponse; import org.springframework.http.HttpHeaders; import org.springframework.lang.Nullable; +import org.springframework.util.CollectionUtils; import org.springframework.util.MultiValueMap; /** @@ -85,7 +85,7 @@ class HttpComponentsHeadersAdapter implements MultiValueMap { @Override public Map toSingleValueMap() { - Map map = new LinkedHashMap<>(size()); + Map map = CollectionUtils.newLinkedHashMap(size()); this.response.headerIterator().forEachRemaining(h -> map.putIfAbsent(h.getName(), h.getValue())); return map; } diff --git a/spring-web/src/main/java/org/springframework/http/client/reactive/JettyHeadersAdapter.java b/spring-web/src/main/java/org/springframework/http/client/reactive/JettyHeadersAdapter.java index dd2544f585..1983c7d433 100644 --- a/spring-web/src/main/java/org/springframework/http/client/reactive/JettyHeadersAdapter.java +++ b/spring-web/src/main/java/org/springframework/http/client/reactive/JettyHeadersAdapter.java @@ -20,7 +20,6 @@ import java.util.AbstractSet; import java.util.Collection; import java.util.Enumeration; import java.util.Iterator; -import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Set; @@ -31,6 +30,7 @@ import org.eclipse.jetty.http.HttpFields; import org.springframework.http.HttpHeaders; import org.springframework.lang.Nullable; +import org.springframework.util.CollectionUtils; import org.springframework.util.MultiValueMap; /** @@ -83,7 +83,7 @@ class JettyHeadersAdapter implements MultiValueMap { @Override public Map toSingleValueMap() { - Map singleValueMap = new LinkedHashMap<>(this.headers.size()); + Map singleValueMap = CollectionUtils.newLinkedHashMap(this.headers.size()); Iterator iterator = this.headers.iterator(); iterator.forEachRemaining(field -> { if (!singleValueMap.containsKey(field.getName())) { diff --git a/spring-web/src/main/java/org/springframework/http/client/reactive/NettyHeadersAdapter.java b/spring-web/src/main/java/org/springframework/http/client/reactive/NettyHeadersAdapter.java index 811d72837a..c0c92750eb 100644 --- a/spring-web/src/main/java/org/springframework/http/client/reactive/NettyHeadersAdapter.java +++ b/spring-web/src/main/java/org/springframework/http/client/reactive/NettyHeadersAdapter.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2020 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. @@ -19,7 +19,6 @@ package org.springframework.http.client.reactive; import java.util.AbstractSet; import java.util.Collection; import java.util.Iterator; -import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Set; @@ -28,6 +27,7 @@ import java.util.stream.Collectors; import io.netty.handler.codec.http.HttpHeaders; import org.springframework.lang.Nullable; +import org.springframework.util.CollectionUtils; import org.springframework.util.MultiValueMap; /** @@ -81,7 +81,7 @@ class NettyHeadersAdapter implements MultiValueMap { @Override public Map toSingleValueMap() { - Map singleValueMap = new LinkedHashMap<>(this.headers.size()); + Map singleValueMap = CollectionUtils.newLinkedHashMap(this.headers.size()); this.headers.entries() .forEach(entry -> { if (!singleValueMap.containsKey(entry.getKey())) { diff --git a/spring-web/src/main/java/org/springframework/http/codec/json/AbstractJackson2Encoder.java b/spring-web/src/main/java/org/springframework/http/codec/json/AbstractJackson2Encoder.java index 2492d433fd..07bb9581e7 100644 --- a/spring-web/src/main/java/org/springframework/http/codec/json/AbstractJackson2Encoder.java +++ b/spring-web/src/main/java/org/springframework/http/codec/json/AbstractJackson2Encoder.java @@ -21,7 +21,6 @@ import java.lang.annotation.Annotation; import java.nio.charset.Charset; import java.util.ArrayList; import java.util.Collections; -import java.util.HashMap; import java.util.List; import java.util.Map; @@ -52,6 +51,7 @@ import org.springframework.http.server.reactive.ServerHttpRequest; import org.springframework.http.server.reactive.ServerHttpResponse; import org.springframework.lang.Nullable; import org.springframework.util.Assert; +import org.springframework.util.CollectionUtils; import org.springframework.util.MimeType; /** @@ -70,7 +70,7 @@ public abstract class AbstractJackson2Encoder extends Jackson2CodecSupport imple private static final Map ENCODINGS; static { - ENCODINGS = new HashMap<>(JsonEncoding.values().length + 1); + ENCODINGS = CollectionUtils.newHashMap(JsonEncoding.values().length); for (JsonEncoding encoding : JsonEncoding.values()) { ENCODINGS.put(encoding.getJavaName(), encoding); } diff --git a/spring-web/src/main/java/org/springframework/http/converter/json/AbstractJackson2HttpMessageConverter.java b/spring-web/src/main/java/org/springframework/http/converter/json/AbstractJackson2HttpMessageConverter.java index 8a6d202300..48e62c789e 100644 --- a/spring-web/src/main/java/org/springframework/http/converter/json/AbstractJackson2HttpMessageConverter.java +++ b/spring-web/src/main/java/org/springframework/http/converter/json/AbstractJackson2HttpMessageConverter.java @@ -24,7 +24,6 @@ import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; import java.util.Arrays; import java.util.Collections; -import java.util.HashMap; import java.util.Map; import java.util.concurrent.atomic.AtomicReference; @@ -56,6 +55,7 @@ import org.springframework.http.converter.HttpMessageNotReadableException; import org.springframework.http.converter.HttpMessageNotWritableException; import org.springframework.lang.Nullable; import org.springframework.util.Assert; +import org.springframework.util.CollectionUtils; import org.springframework.util.TypeUtils; /** @@ -77,7 +77,7 @@ public abstract class AbstractJackson2HttpMessageConverter extends AbstractGener private static final Map ENCODINGS; static { - ENCODINGS = new HashMap<>(JsonEncoding.values().length + 1); + ENCODINGS = CollectionUtils.newHashMap(JsonEncoding.values().length); for (JsonEncoding encoding : JsonEncoding.values()) { ENCODINGS.put(encoding.getJavaName(), encoding); } diff --git a/spring-web/src/main/java/org/springframework/http/server/reactive/JettyHeadersAdapter.java b/spring-web/src/main/java/org/springframework/http/server/reactive/JettyHeadersAdapter.java index 98fd9db212..a31568ad1a 100644 --- a/spring-web/src/main/java/org/springframework/http/server/reactive/JettyHeadersAdapter.java +++ b/spring-web/src/main/java/org/springframework/http/server/reactive/JettyHeadersAdapter.java @@ -20,7 +20,6 @@ import java.util.AbstractSet; import java.util.Collection; import java.util.Enumeration; import java.util.Iterator; -import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Set; @@ -31,6 +30,7 @@ import org.eclipse.jetty.http.HttpFields; import org.springframework.http.HttpHeaders; import org.springframework.lang.Nullable; +import org.springframework.util.CollectionUtils; import org.springframework.util.MultiValueMap; /** @@ -83,7 +83,7 @@ class JettyHeadersAdapter implements MultiValueMap { @Override public Map toSingleValueMap() { - Map singleValueMap = new LinkedHashMap<>(this.headers.size()); + Map singleValueMap = CollectionUtils.newLinkedHashMap(this.headers.size()); Iterator iterator = this.headers.iterator(); iterator.forEachRemaining(field -> { if (!singleValueMap.containsKey(field.getName())) { diff --git a/spring-web/src/main/java/org/springframework/http/server/reactive/NettyHeadersAdapter.java b/spring-web/src/main/java/org/springframework/http/server/reactive/NettyHeadersAdapter.java index d69795b086..4d96585fda 100644 --- a/spring-web/src/main/java/org/springframework/http/server/reactive/NettyHeadersAdapter.java +++ b/spring-web/src/main/java/org/springframework/http/server/reactive/NettyHeadersAdapter.java @@ -19,7 +19,6 @@ package org.springframework.http.server.reactive; import java.util.AbstractSet; import java.util.Collection; import java.util.Iterator; -import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Set; @@ -28,6 +27,7 @@ import java.util.stream.Collectors; import io.netty.handler.codec.http.HttpHeaders; import org.springframework.lang.Nullable; +import org.springframework.util.CollectionUtils; import org.springframework.util.MultiValueMap; /** @@ -81,7 +81,7 @@ class NettyHeadersAdapter implements MultiValueMap { @Override public Map toSingleValueMap() { - Map singleValueMap = new LinkedHashMap<>(this.headers.size()); + Map singleValueMap = CollectionUtils.newLinkedHashMap(this.headers.size()); this.headers.entries() .forEach(entry -> { if (!singleValueMap.containsKey(entry.getKey())) { diff --git a/spring-web/src/main/java/org/springframework/http/server/reactive/TomcatHeadersAdapter.java b/spring-web/src/main/java/org/springframework/http/server/reactive/TomcatHeadersAdapter.java index 10ca124e79..4e305beff8 100644 --- a/spring-web/src/main/java/org/springframework/http/server/reactive/TomcatHeadersAdapter.java +++ b/spring-web/src/main/java/org/springframework/http/server/reactive/TomcatHeadersAdapter.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2020 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. @@ -22,7 +22,6 @@ import java.util.Collections; import java.util.Enumeration; import java.util.HashSet; import java.util.Iterator; -import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Set; @@ -33,6 +32,7 @@ import org.apache.tomcat.util.http.MimeHeaders; import org.springframework.http.HttpHeaders; import org.springframework.lang.Nullable; +import org.springframework.util.CollectionUtils; import org.springframework.util.MultiValueMap; /** @@ -83,7 +83,7 @@ class TomcatHeadersAdapter implements MultiValueMap { @Override public Map toSingleValueMap() { - Map singleValueMap = new LinkedHashMap<>(this.headers.size()); + Map singleValueMap = CollectionUtils.newLinkedHashMap(this.headers.size()); this.keySet().forEach(key -> singleValueMap.put(key, getFirst(key))); return singleValueMap; } diff --git a/spring-web/src/main/java/org/springframework/http/server/reactive/UndertowHeadersAdapter.java b/spring-web/src/main/java/org/springframework/http/server/reactive/UndertowHeadersAdapter.java index bbe1f3df6e..dea9b896e0 100644 --- a/spring-web/src/main/java/org/springframework/http/server/reactive/UndertowHeadersAdapter.java +++ b/spring-web/src/main/java/org/springframework/http/server/reactive/UndertowHeadersAdapter.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2020 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. @@ -19,7 +19,6 @@ package org.springframework.http.server.reactive; import java.util.AbstractSet; import java.util.Collection; import java.util.Iterator; -import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Set; @@ -30,6 +29,7 @@ import io.undertow.util.HeaderValues; import io.undertow.util.HttpString; import org.springframework.lang.Nullable; +import org.springframework.util.CollectionUtils; import org.springframework.util.MultiValueMap; /** @@ -81,7 +81,7 @@ class UndertowHeadersAdapter implements MultiValueMap { @Override public Map toSingleValueMap() { - Map singleValueMap = new LinkedHashMap<>(this.headers.size()); + Map singleValueMap = CollectionUtils.newLinkedHashMap(this.headers.size()); this.headers.forEach(values -> singleValueMap.put(values.getHeaderName().toString(), values.getFirst())); return singleValueMap; diff --git a/spring-web/src/main/java/org/springframework/web/cors/UrlBasedCorsConfigurationSource.java b/spring-web/src/main/java/org/springframework/web/cors/UrlBasedCorsConfigurationSource.java index bec10979fc..5aec15b6d6 100644 --- a/spring-web/src/main/java/org/springframework/web/cors/UrlBasedCorsConfigurationSource.java +++ b/spring-web/src/main/java/org/springframework/web/cors/UrlBasedCorsConfigurationSource.java @@ -17,7 +17,6 @@ package org.springframework.web.cors; import java.util.Collections; -import java.util.HashMap; import java.util.LinkedHashMap; import java.util.Map; @@ -27,6 +26,7 @@ import org.springframework.http.server.PathContainer; import org.springframework.lang.Nullable; import org.springframework.util.AntPathMatcher; import org.springframework.util.Assert; +import org.springframework.util.CollectionUtils; import org.springframework.util.PathMatcher; import org.springframework.web.util.ServletRequestPathUtils; import org.springframework.web.util.UrlPathHelper; @@ -232,7 +232,7 @@ public class UrlBasedCorsConfigurationSource implements CorsConfigurationSource * Return all configured CORS mappings. */ public Map getCorsConfigurations() { - Map result = new HashMap<>(this.corsConfigurations.size()); + Map result = CollectionUtils.newHashMap(this.corsConfigurations.size()); this.corsConfigurations.forEach((pattern, config) -> result.put(pattern.getPatternString(), config)); return Collections.unmodifiableMap(result); } diff --git a/spring-web/src/main/java/org/springframework/web/method/annotation/RequestParamMapMethodArgumentResolver.java b/spring-web/src/main/java/org/springframework/web/method/annotation/RequestParamMapMethodArgumentResolver.java index e4934100b8..221743e715 100644 --- a/spring-web/src/main/java/org/springframework/web/method/annotation/RequestParamMapMethodArgumentResolver.java +++ b/spring-web/src/main/java/org/springframework/web/method/annotation/RequestParamMapMethodArgumentResolver.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2020 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. @@ -26,6 +26,7 @@ import javax.servlet.http.Part; import org.springframework.core.MethodParameter; import org.springframework.core.ResolvableType; import org.springframework.lang.Nullable; +import org.springframework.util.CollectionUtils; import org.springframework.util.LinkedMultiValueMap; import org.springframework.util.MultiValueMap; import org.springframework.util.StringUtils; @@ -115,7 +116,7 @@ public class RequestParamMapMethodArgumentResolver implements HandlerMethodArgum HttpServletRequest servletRequest = webRequest.getNativeRequest(HttpServletRequest.class); if (servletRequest != null && MultipartResolutionDelegate.isMultipartRequest(servletRequest)) { Collection parts = servletRequest.getParts(); - LinkedHashMap result = new LinkedHashMap<>(parts.size()); + LinkedHashMap result = CollectionUtils.newLinkedHashMap(parts.size()); for (Part part : parts) { if (!result.containsKey(part.getName())) { result.put(part.getName(), part); @@ -127,7 +128,7 @@ public class RequestParamMapMethodArgumentResolver implements HandlerMethodArgum } else { Map parameterMap = webRequest.getParameterMap(); - Map result = new LinkedHashMap<>(parameterMap.size()); + Map result = CollectionUtils.newLinkedHashMap(parameterMap.size()); parameterMap.forEach((key, values) -> { if (values.length > 0) { result.put(key, values[0]); diff --git a/spring-web/src/main/java/org/springframework/web/util/UriTemplate.java b/spring-web/src/main/java/org/springframework/web/util/UriTemplate.java index 3c6670ca41..1abf615c8b 100644 --- a/spring-web/src/main/java/org/springframework/web/util/UriTemplate.java +++ b/spring-web/src/main/java/org/springframework/web/util/UriTemplate.java @@ -20,7 +20,6 @@ import java.io.Serializable; import java.net.URI; import java.util.ArrayList; import java.util.Collections; -import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.regex.Matcher; @@ -28,6 +27,7 @@ import java.util.regex.Pattern; import org.springframework.lang.Nullable; import org.springframework.util.Assert; +import org.springframework.util.CollectionUtils; /** * Representation of a URI template that can be expanded with URI variables via @@ -154,7 +154,7 @@ public class UriTemplate implements Serializable { */ public Map match(String uri) { Assert.notNull(uri, "'uri' must not be null"); - Map result = new LinkedHashMap<>(this.variableNames.size()); + Map result = CollectionUtils.newLinkedHashMap(this.variableNames.size()); Matcher matcher = this.matchPattern.matcher(uri); if (matcher.find()) { for (int i = 1; i <= matcher.groupCount(); i++) { diff --git a/spring-web/src/main/java/org/springframework/web/util/UriUtils.java b/spring-web/src/main/java/org/springframework/web/util/UriUtils.java index ca2b9a0a25..4697b3affc 100644 --- a/spring-web/src/main/java/org/springframework/web/util/UriUtils.java +++ b/spring-web/src/main/java/org/springframework/web/util/UriUtils.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2020 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. @@ -20,11 +20,11 @@ import java.net.URI; import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; import java.util.Arrays; -import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import org.springframework.lang.Nullable; +import org.springframework.util.CollectionUtils; import org.springframework.util.LinkedMultiValueMap; import org.springframework.util.MultiValueMap; import org.springframework.util.StringUtils; @@ -325,7 +325,7 @@ public abstract class UriUtils { * @since 5.0 */ public static Map encodeUriVariables(Map uriVariables) { - Map result = new LinkedHashMap<>(uriVariables.size()); + Map result = CollectionUtils.newLinkedHashMap(uriVariables.size()); uriVariables.forEach((key, value) -> { String stringValue = (value != null ? value.toString() : ""); result.put(key, encode(stringValue, StandardCharsets.UTF_8)); diff --git a/spring-web/src/main/java/org/springframework/web/util/UrlPathHelper.java b/spring-web/src/main/java/org/springframework/web/util/UrlPathHelper.java index 83226aa124..44b74611cb 100644 --- a/spring-web/src/main/java/org/springframework/web/util/UrlPathHelper.java +++ b/spring-web/src/main/java/org/springframework/web/util/UrlPathHelper.java @@ -18,7 +18,6 @@ package org.springframework.web.util; import java.net.URLDecoder; import java.nio.charset.UnsupportedCharsetException; -import java.util.LinkedHashMap; import java.util.Map; import java.util.Properties; @@ -32,6 +31,7 @@ import org.apache.commons.logging.LogFactory; import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.ClassUtils; +import org.springframework.util.CollectionUtils; import org.springframework.util.LinkedMultiValueMap; import org.springframework.util.MultiValueMap; import org.springframework.util.StringUtils; @@ -615,7 +615,7 @@ public class UrlPathHelper { return vars; } else { - Map decodedVars = new LinkedHashMap<>(vars.size()); + Map decodedVars = CollectionUtils.newLinkedHashMap(vars.size()); vars.forEach((key, value) -> decodedVars.put(key, decodeInternal(request, value))); return decodedVars; } diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/config/CorsRegistry.java b/spring-webflux/src/main/java/org/springframework/web/reactive/config/CorsRegistry.java index 263e66c15e..d34bc209e7 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/config/CorsRegistry.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/config/CorsRegistry.java @@ -17,10 +17,10 @@ package org.springframework.web.reactive.config; import java.util.ArrayList; -import java.util.LinkedHashMap; import java.util.List; import java.util.Map; +import org.springframework.util.CollectionUtils; import org.springframework.web.cors.CorsConfiguration; /** @@ -55,7 +55,7 @@ public class CorsRegistry { * keyed by path pattern. */ protected Map getCorsConfigurations() { - Map configs = new LinkedHashMap<>(this.registrations.size()); + Map configs = CollectionUtils.newLinkedHashMap(this.registrations.size()); for (CorsRegistration registration : this.registrations) { configs.put(registration.getPathPattern(), registration.getCorsConfiguration()); } 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 ec7de118ab..05850706d4 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 @@ -212,7 +212,7 @@ class DefaultWebClient implements WebClient { private MultiValueMap getCookies() { if (this.cookies == null) { - this.cookies = new LinkedMultiValueMap<>(4); + this.cookies = new LinkedMultiValueMap<>(3); } return this.cookies; } diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/function/client/DefaultWebClientBuilder.java b/spring-webflux/src/main/java/org/springframework/web/reactive/function/client/DefaultWebClientBuilder.java index ed51fb9091..80e79090b0 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/function/client/DefaultWebClientBuilder.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/function/client/DefaultWebClientBuilder.java @@ -180,7 +180,7 @@ final class DefaultWebClientBuilder implements WebClient.Builder { private MultiValueMap initCookies() { if (this.defaultCookies == null) { - this.defaultCookies = new LinkedMultiValueMap<>(4); + this.defaultCookies = new LinkedMultiValueMap<>(3); } return this.defaultCookies; } diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/result/condition/RequestMethodsRequestCondition.java b/spring-webflux/src/main/java/org/springframework/web/reactive/result/condition/RequestMethodsRequestCondition.java index 716d6027e0..3583f8657d 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/result/condition/RequestMethodsRequestCondition.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/result/condition/RequestMethodsRequestCondition.java @@ -19,7 +19,6 @@ package org.springframework.web.reactive.result.condition; import java.util.Arrays; import java.util.Collection; import java.util.Collections; -import java.util.HashMap; import java.util.LinkedHashSet; import java.util.Map; import java.util.Set; @@ -27,6 +26,7 @@ import java.util.Set; import org.springframework.http.HttpMethod; import org.springframework.http.server.reactive.ServerHttpRequest; import org.springframework.lang.Nullable; +import org.springframework.util.CollectionUtils; import org.springframework.util.ObjectUtils; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.cors.reactive.CorsUtils; @@ -45,7 +45,7 @@ public final class RequestMethodsRequestCondition extends AbstractRequestConditi private static final Map requestMethodConditionCache; static { - requestMethodConditionCache = new HashMap<>(RequestMethod.values().length); + requestMethodConditionCache = CollectionUtils.newHashMap(RequestMethod.values().length); for (RequestMethod method : RequestMethod.values()) { requestMethodConditionCache.put( HttpMethod.valueOf(method.name()), new RequestMethodsRequestCondition(method)); diff --git a/spring-webflux/src/test/java/org/springframework/web/reactive/function/server/RenderingResponseIntegrationTests.java b/spring-webflux/src/test/java/org/springframework/web/reactive/function/server/RenderingResponseIntegrationTests.java index 1e8819afd7..00f3b136e5 100644 --- a/spring-webflux/src/test/java/org/springframework/web/reactive/function/server/RenderingResponseIntegrationTests.java +++ b/spring-webflux/src/test/java/org/springframework/web/reactive/function/server/RenderingResponseIntegrationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2020 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. @@ -18,7 +18,6 @@ package org.springframework.web.reactive.function.server; import java.nio.charset.StandardCharsets; import java.util.Collections; -import java.util.LinkedHashMap; import java.util.List; import java.util.Locale; import java.util.Map; @@ -31,6 +30,7 @@ import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.http.server.reactive.ServerHttpResponse; import org.springframework.lang.Nullable; +import org.springframework.util.CollectionUtils; import org.springframework.web.client.RestTemplate; import org.springframework.web.reactive.result.view.View; import org.springframework.web.reactive.result.view.ViewResolver; @@ -103,7 +103,7 @@ class RenderingResponseIntegrationTests extends AbstractRouterFunctionIntegratio private Map parseBody(String body) { String[] lines = body.split("\\n"); - Map result = new LinkedHashMap<>(lines.length); + Map result = CollectionUtils.newLinkedHashMap(lines.length); for (String line : lines) { int idx = line.indexOf('='); String key = line.substring(0, idx); diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/FlashMap.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/FlashMap.java index f47e576eae..c1a814589a 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/FlashMap.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/FlashMap.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2017 the original author or authors. + * Copyright 2002-2020 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. @@ -52,7 +52,7 @@ public final class FlashMap extends HashMap implements Comparabl @Nullable private String targetRequestPath; - private final MultiValueMap targetRequestParams = new LinkedMultiValueMap<>(4); + private final MultiValueMap targetRequestParams = new LinkedMultiValueMap<>(3); private long expirationTime = -1; diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/CorsRegistry.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/CorsRegistry.java index ad93c973ac..23a7903bfb 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/CorsRegistry.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/CorsRegistry.java @@ -17,10 +17,10 @@ package org.springframework.web.servlet.config.annotation; import java.util.ArrayList; -import java.util.LinkedHashMap; import java.util.List; import java.util.Map; +import org.springframework.util.CollectionUtils; import org.springframework.web.cors.CorsConfiguration; /** @@ -56,7 +56,7 @@ public class CorsRegistry { * keyed by path pattern. */ protected Map getCorsConfigurations() { - Map configs = new LinkedHashMap<>(this.registrations.size()); + Map configs = CollectionUtils.newLinkedHashMap(this.registrations.size()); for (CorsRegistration registration : this.registrations) { configs.put(registration.getPathPattern(), registration.getCorsConfiguration()); } diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/condition/RequestMethodsRequestCondition.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/condition/RequestMethodsRequestCondition.java index 96958c2e43..4184239e48 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/condition/RequestMethodsRequestCondition.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/condition/RequestMethodsRequestCondition.java @@ -19,7 +19,6 @@ package org.springframework.web.servlet.mvc.condition; import java.util.Arrays; import java.util.Collection; import java.util.Collections; -import java.util.HashMap; import java.util.LinkedHashSet; import java.util.Map; import java.util.Set; @@ -30,6 +29,7 @@ import javax.servlet.http.HttpServletRequest; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpMethod; import org.springframework.lang.Nullable; +import org.springframework.util.CollectionUtils; import org.springframework.util.ObjectUtils; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.cors.CorsUtils; @@ -48,7 +48,7 @@ public final class RequestMethodsRequestCondition extends AbstractRequestConditi private static final Map requestMethodConditionCache; static { - requestMethodConditionCache = new HashMap<>(RequestMethod.values().length); + requestMethodConditionCache = CollectionUtils.newHashMap(RequestMethod.values().length); for (RequestMethod method : RequestMethod.values()) { requestMethodConditionCache.put(method.name(), new RequestMethodsRequestCondition(method)); } diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/view/AbstractView.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/view/AbstractView.java index 8389b8707d..5df004609b 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/view/AbstractView.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/view/AbstractView.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2020 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. @@ -332,7 +332,7 @@ public abstract class AbstractView extends WebApplicationObjectSupport implement size += (model != null ? model.size() : 0); size += (pathVars != null ? pathVars.size() : 0); - Map mergedModel = new LinkedHashMap<>(size); + Map mergedModel = CollectionUtils.newLinkedHashMap(size); mergedModel.putAll(this.staticAttributes); if (pathVars != null) { mergedModel.putAll(pathVars); diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/view/json/MappingJackson2JsonView.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/view/json/MappingJackson2JsonView.java index b44c7917fe..4bed5c7891 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/view/json/MappingJackson2JsonView.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/view/json/MappingJackson2JsonView.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2020 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. @@ -18,7 +18,6 @@ package org.springframework.web.servlet.view.json; import java.io.IOException; import java.util.Collections; -import java.util.HashMap; import java.util.Map; import java.util.Set; @@ -155,7 +154,7 @@ public class MappingJackson2JsonView extends AbstractJackson2View { */ @Override protected Object filterModel(Map model) { - Map result = new HashMap<>(model.size()); + Map result = CollectionUtils.newHashMap(model.size()); Set modelKeys = (!CollectionUtils.isEmpty(this.modelKeys) ? this.modelKeys : model.keySet()); model.forEach((clazz, value) -> { if (!(value instanceof BindingResult) && modelKeys.contains(clazz) && diff --git a/spring-websocket/src/main/java/org/springframework/web/socket/WebSocketExtension.java b/spring-websocket/src/main/java/org/springframework/web/socket/WebSocketExtension.java index b97d89a7e8..d7bb1b0f04 100644 --- a/spring-websocket/src/main/java/org/springframework/web/socket/WebSocketExtension.java +++ b/spring-websocket/src/main/java/org/springframework/web/socket/WebSocketExtension.java @@ -18,7 +18,6 @@ package org.springframework.web.socket; import java.util.ArrayList; import java.util.Collections; -import java.util.LinkedHashMap; import java.util.List; import java.util.Locale; import java.util.Map; @@ -154,7 +153,7 @@ public class WebSocketExtension { Map parameters = null; if (parts.length > 1) { - parameters = new LinkedHashMap<>(parts.length - 1); + parameters = CollectionUtils.newLinkedHashMap(parts.length - 1); for (int i = 1; i < parts.length; i++) { String parameter = parts[i]; int eqIndex = parameter.indexOf('=');