Avoid resizing of fixed-size HashSet/LinkedHashSet variants

Add helpers to CollectionUtils for building HashSets and LinkedHashSets
that can hold an expected number of elements without needing to
resize/rehash.

Closes gh-32291
This commit is contained in:
Patrick Strawderman 2024-02-18 14:05:31 -08:00 committed by Sam Brannen
parent 6383a0d7ca
commit e1a32d4ba9
47 changed files with 114 additions and 75 deletions

View File

@ -88,6 +88,7 @@ import org.springframework.javapoet.CodeBlock;
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;
import org.springframework.util.StringUtils;
@ -163,7 +164,7 @@ public class AutowiredAnnotationBeanPostProcessor implements SmartInstantiationA
protected final Log logger = LogFactory.getLog(getClass());
private final Set<Class<? extends Annotation>> autowiredAnnotationTypes = new LinkedHashSet<>(4);
private final Set<Class<? extends Annotation>> autowiredAnnotationTypes = CollectionUtils.newLinkedHashSet(4);
private String requiredParameterName = "required";

View File

@ -363,7 +363,7 @@ public class InitDestroyAnnotationBeanPostProcessor implements DestructionAwareB
}
public void checkInitDestroyMethods(RootBeanDefinition beanDefinition) {
Set<LifecycleMethod> checkedInitMethods = new LinkedHashSet<>(this.initMethods.size());
Set<LifecycleMethod> checkedInitMethods = CollectionUtils.newLinkedHashSet(this.initMethods.size());
for (LifecycleMethod lifecycleMethod : this.initMethods) {
String methodIdentifier = lifecycleMethod.getIdentifier();
if (!beanDefinition.isExternallyManagedInitMethod(methodIdentifier)) {
@ -374,7 +374,7 @@ public class InitDestroyAnnotationBeanPostProcessor implements DestructionAwareB
}
}
}
Set<LifecycleMethod> checkedDestroyMethods = new LinkedHashSet<>(this.destroyMethods.size());
Set<LifecycleMethod> checkedDestroyMethods = CollectionUtils.newLinkedHashSet(this.destroyMethods.size());
for (LifecycleMethod lifecycleMethod : this.destroyMethods) {
String methodIdentifier = lifecycleMethod.getIdentifier();
if (!beanDefinition.isExternallyManagedDestroyMethod(methodIdentifier)) {

View File

@ -23,13 +23,13 @@ import java.lang.reflect.Member;
import java.lang.reflect.Method;
import java.util.Collection;
import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.Set;
import org.springframework.beans.MutablePropertyValues;
import org.springframework.beans.PropertyValues;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.lang.Nullable;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ReflectionUtils;
/**
@ -124,7 +124,7 @@ public class InjectionMetadata {
this.checkedElements = Collections.emptySet();
}
else {
Set<InjectedElement> checkedElements = new LinkedHashSet<>((this.injectedElements.size() * 4 / 3) + 1);
Set<InjectedElement> checkedElements = CollectionUtils.newLinkedHashSet(this.injectedElements.size());
for (InjectedElement element : this.injectedElements) {
Member member = element.getMember();
if (!beanDefinition.isExternallyManagedConfigMember(member)) {

View File

@ -19,7 +19,6 @@ package org.springframework.beans.factory.annotation;
import java.lang.annotation.Annotation;
import java.lang.reflect.AnnotatedElement;
import java.lang.reflect.Method;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;
@ -40,6 +39,7 @@ import org.springframework.core.annotation.AnnotationUtils;
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;
/**
@ -59,7 +59,7 @@ import org.springframework.util.ObjectUtils;
*/
public class QualifierAnnotationAutowireCandidateResolver extends GenericTypeAwareAutowireCandidateResolver {
private final Set<Class<? extends Annotation>> qualifierTypes = new LinkedHashSet<>(2);
private final Set<Class<? extends Annotation>> qualifierTypes = CollectionUtils.newLinkedHashSet(2);
private Class<? extends Annotation> valueAnnotationType = Value.class;

View File

@ -18,7 +18,6 @@ package org.springframework.beans.factory.aot;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.LinkedHashSet;
import java.util.Set;
import java.util.stream.Collectors;
@ -34,6 +33,7 @@ import org.springframework.beans.factory.support.RegisteredBean;
import org.springframework.core.MethodParameter;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ReflectionUtils;
import org.springframework.util.function.ThrowingConsumer;
@ -165,7 +165,7 @@ public final class AutowiredMethodArgumentsResolver extends AutowiredElementReso
AutowireCapableBeanFactory autowireCapableBeanFactory = (AutowireCapableBeanFactory) beanFactory;
int argumentCount = method.getParameterCount();
Object[] arguments = new Object[argumentCount];
Set<String> autowiredBeanNames = new LinkedHashSet<>(argumentCount);
Set<String> autowiredBeanNames = CollectionUtils.newLinkedHashSet(argumentCount);
TypeConverter typeConverter = beanFactory.getTypeConverter();
for (int i = 0; i < argumentCount; i++) {
MethodParameter parameter = new MethodParameter(method, i);

View File

@ -22,7 +22,6 @@ import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.lang.reflect.Parameter;
import java.util.Arrays;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;
@ -49,6 +48,7 @@ import org.springframework.core.MethodParameter;
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;
import org.springframework.util.function.ThrowingBiFunction;
@ -289,7 +289,7 @@ public final class BeanInstanceSupplier<T> extends AutowiredElementResolver impl
beanFactory, registeredBean.getBeanName(), beanDefinition, beanFactory.getTypeConverter());
ConstructorArgumentValues values = resolveConstructorArguments(
valueResolver, beanDefinition.getConstructorArgumentValues());
Set<ValueHolder> usedValueHolders = new HashSet<>(parameters.length);
Set<ValueHolder> usedValueHolders = CollectionUtils.newHashSet(parameters.length);
for (int i = 0; i < parameters.length; i++) {
Class<?> parameterType = parameters[i].getType();
String parameterName = (parameters[i].isNamePresent() ? parameters[i].getName() : null);

View File

@ -16,13 +16,13 @@
package org.springframework.beans.factory.config;
import java.util.LinkedHashSet;
import java.util.Set;
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 Set instances. Allows for central setup
@ -85,7 +85,7 @@ public class SetFactoryBean extends AbstractFactoryBean<Set<Object>> {
result = BeanUtils.instantiateClass(this.targetSetClass);
}
else {
result = new LinkedHashSet<>(this.sourceSet.size());
result = CollectionUtils.newLinkedHashSet(this.sourceSet.size());
}
Class<?> valueType = null;
if (this.targetSetClass != null) {

View File

@ -75,6 +75,7 @@ import org.springframework.core.PriorityOrdered;
import org.springframework.core.ResolvableType;
import org.springframework.lang.Nullable;
import org.springframework.util.ClassUtils;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.util.ReflectionUtils;
import org.springframework.util.ReflectionUtils.MethodCallback;
@ -616,7 +617,7 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
}
else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
String[] dependentBeans = getDependentBeans(beanName);
Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);
Set<String> actualDependentBeans = CollectionUtils.newLinkedHashSet(dependentBeans.length);
for (String dependentBean : dependentBeans) {
if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
actualDependentBeans.add(dependentBean);
@ -765,7 +766,7 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
paramNames = pnd.getParameterNames(candidate);
}
}
Set<ConstructorArgumentValues.ValueHolder> usedValueHolders = new HashSet<>(paramTypes.length);
Set<ConstructorArgumentValues.ValueHolder> usedValueHolders = CollectionUtils.newHashSet(paramTypes.length);
Object[] args = new Object[paramTypes.length];
for (int i = 0; i < args.length; i++) {
ConstructorArgumentValues.ValueHolder valueHolder = cav.getArgumentValue(

View File

@ -21,7 +21,6 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
@ -73,6 +72,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.ObjectUtils;
import org.springframework.util.StringUtils;
import org.springframework.util.StringValueResolver;
@ -1152,7 +1152,7 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp
this.prototypesCurrentlyInCreation.set(beanName);
}
else if (curVal instanceof String strValue) {
Set<String> beanNameSet = new HashSet<>(2);
Set<String> beanNameSet = CollectionUtils.newHashSet(2);
beanNameSet.add(strValue);
beanNameSet.add(beanName);
this.prototypesCurrentlyInCreation.set(beanNameSet);

View File

@ -466,7 +466,7 @@ public class BeanDefinitionValueResolver {
* For each element in the managed set, resolve reference if necessary.
*/
private Set<?> resolveManagedSet(Object argName, Set<?> ms) {
Set<Object> resolved = new LinkedHashSet<>(ms.size());
Set<Object> resolved = CollectionUtils.newLinkedHashSet(ms.size());
int i = 0;
for (Object m : ms) {
resolved.add(resolveValueIfNecessary(new KeyedArgName(argName, i), m));

View File

@ -70,6 +70,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.MethodInvoker;
import org.springframework.util.ObjectUtils;
import org.springframework.util.ReflectionUtils;
@ -598,7 +599,7 @@ class ConstructorResolver {
}
}
else if (resolvedValues != null) {
Set<ValueHolder> valueHolders = new LinkedHashSet<>(resolvedValues.getArgumentCount());
Set<ValueHolder> valueHolders = CollectionUtils.newLinkedHashSet(resolvedValues.getArgumentCount());
valueHolders.addAll(resolvedValues.getIndexedArgumentValues().values());
valueHolders.addAll(resolvedValues.getGenericArgumentValues());
for (ValueHolder value : valueHolders) {

View File

@ -28,6 +28,7 @@ import java.util.Map;
import java.util.Set;
import org.springframework.core.io.Resource;
import org.springframework.util.CollectionUtils;
/**
* @author Juergen Hoeller
@ -266,7 +267,7 @@ public class GenericBean<T> {
}
public void setCustomEnumSetMismatch(Set<String> customEnumSet) {
this.customEnumSet = new HashSet<>(customEnumSet.size());
this.customEnumSet = CollectionUtils.newHashSet(customEnumSet.size());
for (String customEnumName : customEnumSet) {
this.customEnumSet.add(CustomEnum.valueOf(customEnumName));
}

View File

@ -17,11 +17,11 @@
package org.springframework.cache.interceptor;
import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.Set;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;
/**
* Base class for cache operations.
@ -158,7 +158,7 @@ public abstract class CacheOperation implements BasicOperation {
}
public void setCacheNames(String... cacheNames) {
this.cacheNames = new LinkedHashSet<>(cacheNames.length);
this.cacheNames = CollectionUtils.newLinkedHashSet(cacheNames.length);
for (String cacheName : cacheNames) {
Assert.hasText(cacheName, "Cache name must be non-empty if specified");
this.cacheNames.add(cacheName);

View File

@ -27,6 +27,7 @@ import org.springframework.beans.factory.InitializingBean;
import org.springframework.cache.Cache;
import org.springframework.cache.CacheManager;
import org.springframework.lang.Nullable;
import org.springframework.util.CollectionUtils;
/**
* Abstract base class implementing the common {@link CacheManager} methods.
@ -64,7 +65,7 @@ public abstract class AbstractCacheManager implements CacheManager, Initializing
synchronized (this.cacheMap) {
this.cacheNames = Collections.emptySet();
this.cacheMap.clear();
Set<String> cacheNames = new LinkedHashSet<>(caches.size());
Set<String> cacheNames = CollectionUtils.newLinkedHashSet(caches.size());
for (Cache cache : caches) {
String name = cache.getName();
this.cacheMap.put(name, decorateCache(cache));

View File

@ -17,7 +17,6 @@
package org.springframework.context.annotation;
import java.lang.annotation.Annotation;
import java.util.LinkedHashSet;
import java.util.Set;
import java.util.function.Predicate;
@ -38,6 +37,7 @@ import org.springframework.core.type.AnnotatedTypeMetadata;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.lang.Nullable;
import org.springframework.util.ClassUtils;
import org.springframework.util.CollectionUtils;
/**
* Utility class that allows for convenient registration of common
@ -154,7 +154,7 @@ public abstract class AnnotationConfigUtils {
}
}
Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<>(8);
Set<BeanDefinitionHolder> beanDefs = CollectionUtils.newLinkedHashSet(6);
if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);

View File

@ -71,6 +71,7 @@ import org.springframework.jndi.support.SimpleJndiBeanFactory;
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;
import org.springframework.util.StringUtils;
@ -148,7 +149,7 @@ public class CommonAnnotationBeanPostProcessor extends InitDestroyAnnotationBean
private static final boolean jndiPresent = ClassUtils.isPresent(
"javax.naming.InitialContext", CommonAnnotationBeanPostProcessor.class.getClassLoader());
private static final Set<Class<? extends Annotation>> resourceAnnotationTypes = new LinkedHashSet<>(4);
private static final Set<Class<? extends Annotation>> resourceAnnotationTypes = CollectionUtils.newLinkedHashSet(3);
@Nullable
private static final Class<? extends Annotation> jakartaResourceType;

View File

@ -437,7 +437,7 @@ class ConfigurationClassParser {
Set<MethodMetadata> asmMethods = asm.getAnnotatedMethods(Bean.class.getName());
if (asmMethods.size() >= beanMethods.size()) {
Set<MethodMetadata> candidateMethods = new LinkedHashSet<>(beanMethods);
Set<MethodMetadata> selectedMethods = new LinkedHashSet<>(asmMethods.size());
Set<MethodMetadata> selectedMethods = CollectionUtils.newLinkedHashSet(asmMethods.size());
for (MethodMetadata asmMethod : asmMethods) {
for (Iterator<MethodMetadata> it = candidateMethods.iterator(); it.hasNext();) {
MethodMetadata beanMethod = it.next();

View File

@ -410,7 +410,7 @@ public class ConfigurationClassPostProcessor implements BeanDefinitionRegistryPo
this.resourceLoader, this.componentScanBeanNameGenerator, registry);
Set<BeanDefinitionHolder> candidates = new LinkedHashSet<>(configCandidates);
Set<ConfigurationClass> alreadyParsed = new HashSet<>(configCandidates.size());
Set<ConfigurationClass> alreadyParsed = CollectionUtils.newHashSet(configCandidates.size());
do {
StartupStep processConfig = this.applicationStartup.start("spring.context.config-classes.parse");
parser.parse(candidates);
@ -433,7 +433,7 @@ public class ConfigurationClassPostProcessor implements BeanDefinitionRegistryPo
if (registry.getBeanDefinitionCount() > candidateNames.length) {
String[] newCandidateNames = registry.getBeanDefinitionNames();
Set<String> oldCandidateNames = Set.of(candidateNames);
Set<String> alreadyParsedClasses = new HashSet<>();
Set<String> alreadyParsedClasses = CollectionUtils.newHashSet(alreadyParsed.size());
for (ConfigurationClass configurationClass : alreadyParsed) {
alreadyParsedClasses.add(configurationClass.getMetadata().getClassName());
}

View File

@ -21,7 +21,6 @@ import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
@ -883,7 +882,7 @@ public class MBeanExporter extends MBeanRegistrationSupport implements MBeanExpo
*/
private void autodetect(Map<String, Object> beans, AutodetectCallback callback) {
Assert.state(this.beanFactory != null, "No BeanFactory set");
Set<String> beanNames = new LinkedHashSet<>(this.beanFactory.getBeanDefinitionCount());
Set<String> beanNames = CollectionUtils.newLinkedHashSet(this.beanFactory.getBeanDefinitionCount());
Collections.addAll(beanNames, this.beanFactory.getBeanDefinitionNames());
if (this.beanFactory instanceof ConfigurableBeanFactory cbf) {
Collections.addAll(beanNames, cbf.getSingletonNames());

View File

@ -18,7 +18,6 @@ package org.springframework.scheduling.annotation;
import java.lang.annotation.Annotation;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.Set;
import java.util.concurrent.Executor;
import java.util.function.Supplier;
@ -35,6 +34,7 @@ import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import org.springframework.util.CollectionUtils;
import org.springframework.util.function.SingletonSupplier;
/**
@ -94,7 +94,7 @@ public class AsyncAnnotationAdvisor extends AbstractPointcutAdvisor implements B
public AsyncAnnotationAdvisor(
@Nullable Supplier<Executor> executor, @Nullable Supplier<AsyncUncaughtExceptionHandler> exceptionHandler) {
Set<Class<? extends Annotation>> asyncAnnotationTypes = new LinkedHashSet<>(2);
Set<Class<? extends Annotation>> asyncAnnotationTypes = CollectionUtils.newLinkedHashSet(2);
asyncAnnotationTypes.add(Async.class);
ClassLoader classLoader = AsyncAnnotationAdvisor.class.getClassLoader();

View File

@ -18,7 +18,6 @@ package org.springframework.core.convert.support;
import java.lang.reflect.Array;
import java.util.Collection;
import java.util.LinkedHashSet;
import java.util.Optional;
import java.util.Set;
@ -26,6 +25,7 @@ import org.springframework.core.convert.ConversionService;
import org.springframework.core.convert.TypeDescriptor;
import org.springframework.core.convert.converter.ConditionalGenericConverter;
import org.springframework.lang.Nullable;
import org.springframework.util.CollectionUtils;
/**
* Convert an Object to {@code java.util.Optional<T>} if necessary using the
@ -48,7 +48,7 @@ final class ObjectToOptionalConverter implements ConditionalGenericConverter {
@Override
public Set<ConvertiblePair> getConvertibleTypes() {
Set<ConvertiblePair> convertibleTypes = new LinkedHashSet<>(4);
Set<ConvertiblePair> convertibleTypes = CollectionUtils.newLinkedHashSet(3);
convertibleTypes.add(new ConvertiblePair(Collection.class, Optional.class));
convertibleTypes.add(new ConvertiblePair(Object[].class, Optional.class));
convertibleTypes.add(new ConvertiblePair(Object.class, Optional.class));

View File

@ -24,6 +24,7 @@ import java.util.List;
import java.util.Set;
import org.springframework.lang.Nullable;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
/**
@ -89,7 +90,7 @@ public class CompositePropertySource extends EnumerablePropertySource<Object> {
namesList.add(names);
total += names.length;
}
Set<String> allNames = new LinkedHashSet<>(total);
Set<String> allNames = CollectionUtils.newLinkedHashSet(total);
namesList.forEach(names -> Collections.addAll(allNames, names));
return StringUtils.toStringArray(allNames);
}

View File

@ -30,7 +30,6 @@ import java.nio.channels.WritableByteChannel;
import java.nio.file.OpenOption;
import java.nio.file.Path;
import java.nio.file.StandardOpenOption;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.Callable;
import java.util.concurrent.Executor;
@ -54,6 +53,7 @@ import reactor.util.context.Context;
import org.springframework.core.io.Resource;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;
/**
* Utility class for working with {@link DataBuffer DataBuffers}.
@ -382,7 +382,7 @@ public abstract class DataBufferUtils {
private static Set<OpenOption> checkWriteOptions(OpenOption[] options) {
int length = options.length;
Set<OpenOption> result = new HashSet<>(length + 3);
Set<OpenOption> result = CollectionUtils.newHashSet(length > 0 ? length : 2);
if (length == 0) {
result.add(StandardOpenOption.CREATE);
result.add(StandardOpenOption.TRUNCATE_EXISTING);

View File

@ -22,8 +22,10 @@ import java.util.Collection;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Properties;
@ -85,7 +87,7 @@ public abstract class CollectionUtils {
* @see #newLinkedHashMap(int)
*/
public static <K, V> HashMap<K, V> newHashMap(int expectedSize) {
return new HashMap<>(computeMapInitialCapacity(expectedSize), DEFAULT_LOAD_FACTOR);
return new HashMap<>(computeInitialCapacity(expectedSize), DEFAULT_LOAD_FACTOR);
}
/**
@ -102,10 +104,34 @@ public abstract class CollectionUtils {
* @see #newHashMap(int)
*/
public static <K, V> LinkedHashMap<K, V> newLinkedHashMap(int expectedSize) {
return new LinkedHashMap<>(computeMapInitialCapacity(expectedSize), DEFAULT_LOAD_FACTOR);
return new LinkedHashMap<>(computeInitialCapacity(expectedSize), DEFAULT_LOAD_FACTOR);
}
private static int computeMapInitialCapacity(int expectedSize) {
/**
* Instantiate a new {@link HashSet} with an initial capacity
* that can accommodate the specified number of elements without
* any immediate resize/rehash operations to be expected.
* @param expectedSize the expected number of elements (with a corresponding
* capacity to be derived so that no resize/rehash operations are needed)
* @see #newLinkedHashSet(int)
*/
public static <E> HashSet<E> newHashSet(int expectedSize) {
return new HashSet<>(computeInitialCapacity(expectedSize), DEFAULT_LOAD_FACTOR);
}
/**
* Instantiate a new {@link LinkedHashSet} with an initial capacity
* that can accommodate the specified number of elements without
* any immediate resize/rehash operations to be expected.
* @param expectedSize the expected number of elements (with a corresponding
* capacity to be derived so that no resize/rehash operations are needed)
* @see #newHashSet(int)
*/
public static <E> LinkedHashSet<E> newLinkedHashSet(int expectedSize) {
return new LinkedHashSet<>(computeInitialCapacity(expectedSize), DEFAULT_LOAD_FACTOR);
}
private static int computeInitialCapacity(int expectedSize) {
return (int) Math.ceil(expectedSize / (double) DEFAULT_LOAD_FACTOR);
}

View File

@ -18,7 +18,6 @@ package org.springframework.jdbc.core.metadata;
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
@ -215,7 +214,7 @@ public class TableMetaDataContext {
if (!declaredColumns.isEmpty()) {
return new ArrayList<>(declaredColumns);
}
Set<String> keys = new LinkedHashSet<>(generatedKeyNames.length);
Set<String> keys = CollectionUtils.newLinkedHashSet(generatedKeyNames.length);
for (String key : generatedKeyNames) {
keys.add(key.toUpperCase());
}
@ -296,7 +295,7 @@ public class TableMetaDataContext {
* @return the insert string to be used
*/
public String createInsertString(String... generatedKeyNames) {
Set<String> keys = new LinkedHashSet<>(generatedKeyNames.length);
Set<String> keys = CollectionUtils.newLinkedHashSet(generatedKeyNames.length);
for (String key : generatedKeyNames) {
keys.add(key.toUpperCase());
}

View File

@ -86,7 +86,7 @@ public class DestinationPatternsMessageCondition
private static Set<String> prependLeadingSlash(String[] patterns, RouteMatcher routeMatcher) {
boolean slashSeparator = routeMatcher.combine("a", "a").equals("a/a");
Set<String> result = new LinkedHashSet<>(patterns.length);
Set<String> result = CollectionUtils.newLinkedHashSet(patterns.length);
for (String pattern : patterns) {
if (slashSeparator && StringUtils.hasLength(pattern) && !pattern.startsWith("/")) {
pattern = "/" + pattern;

View File

@ -30,6 +30,7 @@ import org.springframework.messaging.simp.SimpLogging;
import org.springframework.messaging.simp.SimpMessageHeaderAccessor;
import org.springframework.messaging.simp.SimpMessageType;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
/**
@ -216,7 +217,7 @@ public class DefaultUserDestinationResolver implements UserDestinationResolver {
}
else {
Set<SimpSession> sessions = user.getSessions();
sessionIds = new HashSet<>(sessions.size());
sessionIds = CollectionUtils.newHashSet(sessions.size());
for (SimpSession session : sessions) {
sessionIds.add(session.getId());
}

View File

@ -414,7 +414,7 @@ public class MultiServerUserRegistry implements SimpUserRegistry, SmartApplicati
this.id = session.getId();
this.user = new TransferSimpUser();
Set<SimpSubscription> subscriptions = session.getSubscriptions();
this.subscriptions = new HashSet<>(subscriptions.size());
this.subscriptions = CollectionUtils.newHashSet(subscriptions.size());
for (SimpSubscription subscription : subscriptions) {
this.subscriptions.add(new TransferSimpSubscription(subscription));
}

View File

@ -52,6 +52,7 @@ import org.springframework.http.MediaTypeFactory;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import org.springframework.util.CollectionUtils;
import org.springframework.util.MimeType;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
@ -303,7 +304,7 @@ public class MockServletContext implements ServletContext {
if (ObjectUtils.isEmpty(fileList)) {
return null;
}
Set<String> resourcePaths = new LinkedHashSet<>(fileList.length);
Set<String> resourcePaths = CollectionUtils.newLinkedHashSet(fileList.length);
for (String fileEntry : fileList) {
String resultPath = actualPath + fileEntry;
if (resource.createRelative(fileEntry).getFile().isDirectory()) {

View File

@ -20,7 +20,6 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
@ -53,6 +52,7 @@ import org.springframework.test.context.TestExecutionListeners.MergeMode;
import org.springframework.test.context.util.TestContextSpringFactoriesUtils;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
/**
@ -355,7 +355,7 @@ public abstract class AbstractTestContextBootstrapper implements TestContextBoot
List<ContextConfigurationAttributes> configAttributes) {
List<ContextCustomizerFactory> factories = getContextCustomizerFactories(testClass);
Set<ContextCustomizer> customizers = new LinkedHashSet<>(factories.size());
Set<ContextCustomizer> customizers = CollectionUtils.newLinkedHashSet(factories.size());
for (ContextCustomizerFactory factory : factories) {
ContextCustomizer customizer = factory.createContextCustomizer(testClass, configAttributes);
if (customizer != null) {

View File

@ -19,7 +19,6 @@ package org.springframework.test.context.support;
import java.lang.annotation.Annotation;
import java.lang.reflect.Constructor;
import java.lang.reflect.Executable;
import java.util.LinkedHashSet;
import java.util.Set;
import org.apache.commons.logging.Log;
@ -33,6 +32,7 @@ import org.springframework.test.context.TestConstructor;
import org.springframework.test.context.TestConstructor.AutowireMode;
import org.springframework.test.context.TestContextAnnotationUtils;
import org.springframework.util.ClassUtils;
import org.springframework.util.CollectionUtils;
/**
* Utility methods for working with {@link TestConstructor @TestConstructor}.
@ -49,7 +49,7 @@ public abstract class TestConstructorUtils {
private static final Log logger = LogFactory.getLog(TestConstructorUtils.class);
private static final Set<Class<? extends Annotation>> autowiredAnnotationTypes = new LinkedHashSet<>(2);
private static final Set<Class<? extends Annotation>> autowiredAnnotationTypes = CollectionUtils.newLinkedHashSet(2);
static {
autowiredAnnotationTypes.add(Autowired.class);

View File

@ -29,6 +29,7 @@ import org.springframework.transaction.interceptor.AbstractFallbackTransactionAt
import org.springframework.transaction.interceptor.TransactionAttribute;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import org.springframework.util.CollectionUtils;
/**
* Implementation of the
@ -92,7 +93,7 @@ public class AnnotationTransactionAttributeSource extends AbstractFallbackTransa
public AnnotationTransactionAttributeSource(boolean publicMethodsOnly) {
this.publicMethodsOnly = publicMethodsOnly;
if (jta12Present || ejb3Present) {
this.annotationParsers = new LinkedHashSet<>(4);
this.annotationParsers = CollectionUtils.newLinkedHashSet(3);
this.annotationParsers.add(new SpringTransactionAnnotationParser());
if (jta12Present) {
this.annotationParsers.add(new JtaTransactionAnnotationParser());

View File

@ -18,11 +18,11 @@ package org.springframework.transaction.interceptor;
import java.util.Collection;
import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.Set;
import org.springframework.lang.Nullable;
import org.springframework.transaction.support.DefaultTransactionDefinition;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.util.StringValueResolver;
@ -216,7 +216,7 @@ public class DefaultTransactionAttribute extends DefaultTransactionDefinition im
if (this.qualifier != null) {
this.qualifier = resolver.resolveStringValue(this.qualifier);
}
Set<String> resolvedLabels = new LinkedHashSet<>(this.labels.size());
Set<String> resolvedLabels = CollectionUtils.newLinkedHashSet(this.labels.size());
for (String label : this.labels) {
resolvedLabels.add(resolver.resolveStringValue(label));
}

View File

@ -34,7 +34,6 @@ import java.util.ArrayList;
import java.util.Base64;
import java.util.Collection;
import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
@ -752,7 +751,7 @@ public class HttpHeaders implements MultiValueMap<String, String>, Serializable
String value = getFirst(ALLOW);
if (StringUtils.hasLength(value)) {
String[] tokens = StringUtils.tokenizeToStringArray(value, ",");
Set<HttpMethod> result = new LinkedHashSet<>(tokens.length);
Set<HttpMethod> result = CollectionUtils.newLinkedHashSet(tokens.length);
for (String token : tokens) {
HttpMethod method = HttpMethod.valueOf(token);
result.add(method);

View File

@ -22,7 +22,6 @@ import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
@ -163,7 +162,7 @@ public final class HttpComponentsHeadersAdapter implements MultiValueMap<String,
@Override
public Set<String> keySet() {
Set<String> keys = new LinkedHashSet<>(size());
Set<String> keys = CollectionUtils.newLinkedHashSet(size());
for (Header header : this.message.getHeaders()) {
keys.add(header.getName());
}

View File

@ -17,7 +17,6 @@
package org.springframework.web;
import java.util.Collection;
import java.util.LinkedHashSet;
import java.util.Set;
import jakarta.servlet.ServletException;
@ -28,6 +27,7 @@ import org.springframework.http.HttpStatus;
import org.springframework.http.HttpStatusCode;
import org.springframework.http.ProblemDetail;
import org.springframework.lang.Nullable;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
@ -107,7 +107,7 @@ public class HttpRequestMethodNotSupportedException extends ServletException imp
if (this.supportedMethods == null) {
return null;
}
Set<HttpMethod> supportedMethods = new LinkedHashSet<>(this.supportedMethods.length);
Set<HttpMethod> supportedMethods = CollectionUtils.newLinkedHashSet(this.supportedMethods.length);
for (String value : this.supportedMethods) {
HttpMethod method = HttpMethod.valueOf(value);
supportedMethods.add(method);

View File

@ -18,7 +18,6 @@ package org.springframework.web.accept;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
@ -29,6 +28,7 @@ import java.util.concurrent.CopyOnWriteArrayList;
import org.springframework.http.MediaType;
import org.springframework.lang.Nullable;
import org.springframework.util.CollectionUtils;
/**
* An implementation of {@code MediaTypeFileExtensionResolver} that maintains
@ -55,7 +55,7 @@ public class MappingMediaTypeFileExtensionResolver implements MediaTypeFileExten
*/
public MappingMediaTypeFileExtensionResolver(@Nullable Map<String, MediaType> mediaTypes) {
if (mediaTypes != null) {
Set<String> allFileExtensions = new HashSet<>(mediaTypes.size());
Set<String> allFileExtensions = CollectionUtils.newHashSet(mediaTypes.size());
mediaTypes.forEach((extension, mediaType) -> {
String lowerCaseExtension = extension.toLowerCase(Locale.ENGLISH);
this.mediaTypes.put(lowerCaseExtension, mediaType);

View File

@ -19,7 +19,6 @@ package org.springframework.web.cors;
import java.time.Duration;
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
import java.util.function.Consumer;
@ -657,7 +656,7 @@ public class CorsConfiguration {
if (source.contains(ALL) || other.contains(ALL)) {
return ALL_LIST;
}
Set<String> combined = new LinkedHashSet<>(source.size() + other.size());
Set<String> combined = CollectionUtils.newLinkedHashSet(source.size() + other.size());
combined.addAll(source);
combined.addAll(other);
return new ArrayList<>(combined);
@ -675,7 +674,7 @@ public class CorsConfiguration {
if (source.contains(ALL_PATTERN) || other.contains(ALL_PATTERN)) {
return ALL_PATTERN_LIST;
}
Set<OriginPattern> combined = new LinkedHashSet<>(source.size() + other.size());
Set<OriginPattern> combined = CollectionUtils.newLinkedHashSet(source.size() + other.size());
combined.addAll(source);
combined.addAll(other);
return new ArrayList<>(combined);

View File

@ -37,6 +37,7 @@ import jakarta.servlet.http.Part;
import org.springframework.http.ContentDisposition;
import org.springframework.http.HttpHeaders;
import org.springframework.lang.Nullable;
import org.springframework.util.CollectionUtils;
import org.springframework.util.FileCopyUtils;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
@ -91,7 +92,7 @@ public class StandardMultipartHttpServletRequest extends AbstractMultipartHttpSe
private void parseRequest(HttpServletRequest request) {
try {
Collection<Part> parts = request.getParts();
this.multipartParameterNames = new LinkedHashSet<>(parts.size());
this.multipartParameterNames = CollectionUtils.newLinkedHashSet(parts.size());
MultiValueMap<String, MultipartFile> files = new LinkedMultiValueMap<>(parts.size());
for (Part part : parts) {
String headerValue = part.getHeader(HttpHeaders.CONTENT_DISPOSITION);

View File

@ -52,6 +52,7 @@ import org.springframework.http.MediaTypeFactory;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import org.springframework.util.CollectionUtils;
import org.springframework.util.MimeType;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
@ -303,7 +304,7 @@ public class MockServletContext implements ServletContext {
if (ObjectUtils.isEmpty(fileList)) {
return null;
}
Set<String> resourcePaths = new LinkedHashSet<>(fileList.length);
Set<String> resourcePaths = CollectionUtils.newLinkedHashSet(fileList.length);
for (String fileEntry : fileList) {
String resultPath = actualPath + fileEntry;
if (resource.createRelative(fileEntry).getFile().isDirectory()) {

View File

@ -22,6 +22,7 @@ import java.util.LinkedHashSet;
import java.util.Set;
import org.springframework.lang.Nullable;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.cors.reactive.CorsUtils;
@ -65,7 +66,7 @@ public final class HeadersRequestCondition extends AbstractRequestCondition<Head
if ("Accept".equalsIgnoreCase(expr.name) || "Content-Type".equalsIgnoreCase(expr.name)) {
continue;
}
result = (result != null ? result : new LinkedHashSet<>(headers.length));
result = (result != null ? result : CollectionUtils.newLinkedHashSet(headers.length));
result.add(expr);
}
}

View File

@ -22,6 +22,7 @@ import java.util.LinkedHashSet;
import java.util.Set;
import org.springframework.lang.Nullable;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.server.ServerWebExchange;
@ -51,7 +52,7 @@ public final class ParamsRequestCondition extends AbstractRequestCondition<Param
if (ObjectUtils.isEmpty(params)) {
return Collections.emptySet();
}
Set<ParamExpression> result = new LinkedHashSet<>(params.length);
Set<ParamExpression> result = CollectionUtils.newLinkedHashSet(params.length);
for (String param : params) {
result.add(new ParamExpression(param));
}

View File

@ -24,6 +24,7 @@ import java.util.Set;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.lang.Nullable;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.cors.CorsUtils;
@ -67,7 +68,7 @@ public final class HeadersRequestCondition extends AbstractRequestCondition<Head
if ("Accept".equalsIgnoreCase(expr.name) || "Content-Type".equalsIgnoreCase(expr.name)) {
continue;
}
result = (result != null ? result : new LinkedHashSet<>(headers.length));
result = (result != null ? result : CollectionUtils.newLinkedHashSet(headers.length));
result.add(expr);
}
}

View File

@ -25,6 +25,7 @@ import java.util.Set;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.lang.Nullable;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.util.WebUtils;
@ -55,7 +56,7 @@ public final class ParamsRequestCondition extends AbstractRequestCondition<Param
if (ObjectUtils.isEmpty(params)) {
return Collections.emptySet();
}
Set<ParamExpression> expressions = new LinkedHashSet<>(params.length);
Set<ParamExpression> expressions = CollectionUtils.newLinkedHashSet(params.length);
for (String param : params) {
expressions.add(new ParamExpression(param));
}

View File

@ -30,6 +30,7 @@ import jakarta.servlet.http.HttpServletRequest;
import org.springframework.lang.Nullable;
import org.springframework.util.AntPathMatcher;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.util.PathMatcher;
import org.springframework.util.StringUtils;
@ -157,7 +158,7 @@ public class PatternsRequestCondition extends AbstractRequestCondition<PatternsR
if (!hasPattern(patterns)) {
return EMPTY_PATH_PATTERN;
}
Set<String> result = new LinkedHashSet<>(patterns.length);
Set<String> result = CollectionUtils.newLinkedHashSet(patterns.length);
for (String pattern : patterns) {
pattern = PathPatternParser.defaultInstance.initFullPathPattern(pattern);
result.add(pattern);

View File

@ -512,7 +512,7 @@ public abstract class RequestMappingInfoHandlerMapping extends AbstractHandlerMe
}
private static Set<HttpMethod> initAllowedHttpMethods(Set<String> declaredMethods) {
Set<HttpMethod> result = new LinkedHashSet<>(declaredMethods.size());
Set<HttpMethod> result = CollectionUtils.newLinkedHashSet(declaredMethods.size());
if (declaredMethods.isEmpty()) {
for (HttpMethod method : HttpMethod.values()) {
if (method != HttpMethod.TRACE) {

View File

@ -32,6 +32,7 @@ import org.springframework.http.CacheControl;
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.util.StringUtils;
import org.springframework.web.HttpRequestMethodNotSupportedException;
@ -130,7 +131,7 @@ public abstract class WebContentGenerator extends WebApplicationObjectSupport {
*/
public WebContentGenerator(boolean restrictDefaultSupportedMethods) {
if (restrictDefaultSupportedMethods) {
this.supportedMethods = new LinkedHashSet<>(4);
this.supportedMethods = CollectionUtils.newLinkedHashSet(3);
this.supportedMethods.add(METHOD_GET);
this.supportedMethods.add(METHOD_HEAD);
this.supportedMethods.add(METHOD_POST);