From 01f717375be65d82df61441c8dced6ca6189eca7 Mon Sep 17 00:00:00 2001 From: Stephane Nicoll Date: Fri, 25 Aug 2023 15:20:24 +0200 Subject: [PATCH] Introduce ObjectUtils#nullSafeHash(Object... element) This commit deprecates the various nullSafeHashCode methods taking array types as they are superseded by Arrays.hashCode now. This means that the now only remaining nullSafeHashCode method does not trigger a warning only if the target type is not an array. At the same time, there are multiple use of this method on several elements, handling the accumulation of hash codes. For that reason, this commit also introduces a nullSafeHash that takes an array of elements. The only difference between Objects.hash is that this method handles arrays. The codebase has been reviewed to use any of those two methods when it is possible. Closes gh-29051 --- .../aspectj/AspectJExpressionPointcut.java | 7 +- .../aop/aspectj/TypePatternClassFilter.java | 4 +- .../aop/support/ClassFilters.java | 4 +- .../AbstractBeanFactoryBasedTargetSource.java | 3 +- .../aop/target/EmptyTargetSource.java | 3 +- .../cache/config/TestEntity.java | 4 +- .../beans/BeanMetadataAttribute.java | 2 +- .../beans/ExtendedBeanInfo.java | 10 +- .../GenericTypeAwarePropertyDescriptor.java | 7 +- .../springframework/beans/PropertyValue.java | 2 +- .../beans/factory/InjectionPoint.java | 5 +- .../factory/config/BeanDefinitionHolder.java | 6 +- .../config/ConstructorArgumentValues.java | 2 +- .../factory/config/TypedStringValue.java | 2 +- .../beans/factory/support/MethodOverride.java | 4 +- .../mail/SimpleMailMessage.java | 10 +- .../AbstractApplicationEventMulticaster.java | 3 +- .../support/ApplicationListenerDetector.java | 4 +- .../DefaultMessageSourceResolvable.java | 5 +- .../support/NotificationListenerHolder.java | 7 +- .../testfixture/cache/beans/TestEntity.java | 4 +- .../core/annotation/RepeatableContainers.java | 3 +- .../core/convert/Property.java | 3 +- .../core/env/PropertySource.java | 4 +- .../org/springframework/util/ObjectUtils.java | 155 ++++------ .../util/ObjectUtilsTests.java | 271 +++++++++--------- .../simp/user/MultiServerUserRegistry.java | 3 +- .../messaging/support/GenericMessage.java | 2 +- .../simp/user/TestSimpSubscription.java | 4 +- .../springframework/r2dbc/core/Parameter.java | 2 +- .../http/ContentDisposition.java | 11 +- .../org/springframework/http/HttpEntity.java | 4 +- .../org/springframework/http/HttpRange.java | 4 +- .../springframework/http/ProblemDetail.java | 10 +- .../web/util/HierarchicalUriComponents.java | 11 +- .../web/util/OpaqueUriComponents.java | 6 +- .../web/reactive/socket/CloseStatus.java | 4 +- .../web/socket/CloseStatus.java | 3 +- 38 files changed, 276 insertions(+), 322 deletions(-) diff --git a/spring-aop/src/main/java/org/springframework/aop/aspectj/AspectJExpressionPointcut.java b/spring-aop/src/main/java/org/springframework/aop/aspectj/AspectJExpressionPointcut.java index c6ee43b2ec..1b33b11225 100644 --- a/spring-aop/src/main/java/org/springframework/aop/aspectj/AspectJExpressionPointcut.java +++ b/spring-aop/src/main/java/org/springframework/aop/aspectj/AspectJExpressionPointcut.java @@ -525,11 +525,8 @@ public class AspectJExpressionPointcut extends AbstractExpressionPointcut @Override public int hashCode() { - int hashCode = ObjectUtils.nullSafeHashCode(getExpression()); - hashCode = 31 * hashCode + ObjectUtils.nullSafeHashCode(this.pointcutDeclarationScope); - hashCode = 31 * hashCode + ObjectUtils.nullSafeHashCode(this.pointcutParameterNames); - hashCode = 31 * hashCode + ObjectUtils.nullSafeHashCode(this.pointcutParameterTypes); - return hashCode; + return ObjectUtils.nullSafeHash(getExpression(), this.pointcutDeclarationScope, + this.pointcutParameterNames, this.pointcutParameterTypes); } @Override diff --git a/spring-aop/src/main/java/org/springframework/aop/aspectj/TypePatternClassFilter.java b/spring-aop/src/main/java/org/springframework/aop/aspectj/TypePatternClassFilter.java index bc6de39639..d6ddae2671 100644 --- a/spring-aop/src/main/java/org/springframework/aop/aspectj/TypePatternClassFilter.java +++ b/spring-aop/src/main/java/org/springframework/aop/aspectj/TypePatternClassFilter.java @@ -16,6 +16,8 @@ package org.springframework.aop.aspectj; +import java.util.Objects; + import org.aspectj.weaver.tools.PointcutParser; import org.aspectj.weaver.tools.TypePatternMatcher; @@ -124,7 +126,7 @@ public class TypePatternClassFilter implements ClassFilter { @Override public int hashCode() { - return ObjectUtils.nullSafeHashCode(this.typePattern); + return Objects.hashCode(this.typePattern); } @Override diff --git a/spring-aop/src/main/java/org/springframework/aop/support/ClassFilters.java b/spring-aop/src/main/java/org/springframework/aop/support/ClassFilters.java index fa24bb1050..5b7f3b055d 100644 --- a/spring-aop/src/main/java/org/springframework/aop/support/ClassFilters.java +++ b/spring-aop/src/main/java/org/springframework/aop/support/ClassFilters.java @@ -129,7 +129,7 @@ public abstract class ClassFilters { @Override public int hashCode() { - return ObjectUtils.nullSafeHashCode(this.filters); + return Arrays.hashCode(this.filters); } @Override @@ -170,7 +170,7 @@ public abstract class ClassFilters { @Override public int hashCode() { - return ObjectUtils.nullSafeHashCode(this.filters); + return Arrays.hashCode(this.filters); } @Override diff --git a/spring-aop/src/main/java/org/springframework/aop/target/AbstractBeanFactoryBasedTargetSource.java b/spring-aop/src/main/java/org/springframework/aop/target/AbstractBeanFactoryBasedTargetSource.java index 4c78958795..5bb7929b2d 100644 --- a/spring-aop/src/main/java/org/springframework/aop/target/AbstractBeanFactoryBasedTargetSource.java +++ b/spring-aop/src/main/java/org/springframework/aop/target/AbstractBeanFactoryBasedTargetSource.java @@ -17,6 +17,7 @@ package org.springframework.aop.target; import java.io.Serializable; +import java.util.Objects; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -190,7 +191,7 @@ public abstract class AbstractBeanFactoryBasedTargetSource implements TargetSour @Override public int hashCode() { - return getClass().hashCode() * 13 + ObjectUtils.nullSafeHashCode(this.targetBeanName); + return Objects.hash(getClass(), this.targetBeanName); } @Override diff --git a/spring-aop/src/main/java/org/springframework/aop/target/EmptyTargetSource.java b/spring-aop/src/main/java/org/springframework/aop/target/EmptyTargetSource.java index 1486cff2a9..6b0fdfd498 100644 --- a/spring-aop/src/main/java/org/springframework/aop/target/EmptyTargetSource.java +++ b/spring-aop/src/main/java/org/springframework/aop/target/EmptyTargetSource.java @@ -17,6 +17,7 @@ package org.springframework.aop.target; import java.io.Serializable; +import java.util.Objects; import org.springframework.aop.TargetSource; import org.springframework.lang.Nullable; @@ -140,7 +141,7 @@ public final class EmptyTargetSource implements TargetSource, Serializable { @Override public int hashCode() { - return EmptyTargetSource.class.hashCode() * 13 + ObjectUtils.nullSafeHashCode(this.targetClass); + return Objects.hash(getClass(), this.targetClass); } @Override diff --git a/spring-aspects/src/test/java/org/springframework/cache/config/TestEntity.java b/spring-aspects/src/test/java/org/springframework/cache/config/TestEntity.java index 62d78b7159..0219086ed4 100644 --- a/spring-aspects/src/test/java/org/springframework/cache/config/TestEntity.java +++ b/spring-aspects/src/test/java/org/springframework/cache/config/TestEntity.java @@ -16,6 +16,8 @@ package org.springframework.cache.config; +import java.util.Objects; + import org.springframework.lang.Nullable; import org.springframework.util.ObjectUtils; @@ -42,7 +44,7 @@ public class TestEntity { @Override public int hashCode() { - return ObjectUtils.nullSafeHashCode(this.id); + return Objects.hashCode(this.id); } @Override diff --git a/spring-beans/src/main/java/org/springframework/beans/BeanMetadataAttribute.java b/spring-beans/src/main/java/org/springframework/beans/BeanMetadataAttribute.java index 28d09d49ff..f5c8a854ad 100644 --- a/spring-beans/src/main/java/org/springframework/beans/BeanMetadataAttribute.java +++ b/spring-beans/src/main/java/org/springframework/beans/BeanMetadataAttribute.java @@ -90,7 +90,7 @@ public class BeanMetadataAttribute implements BeanMetadataElement { @Override public int hashCode() { - return this.name.hashCode() * 29 + ObjectUtils.nullSafeHashCode(this.value); + return ObjectUtils.nullSafeHash(this.name, this.value); } @Override diff --git a/spring-beans/src/main/java/org/springframework/beans/ExtendedBeanInfo.java b/spring-beans/src/main/java/org/springframework/beans/ExtendedBeanInfo.java index 76ef87f3fa..df2f133337 100644 --- a/spring-beans/src/main/java/org/springframework/beans/ExtendedBeanInfo.java +++ b/spring-beans/src/main/java/org/springframework/beans/ExtendedBeanInfo.java @@ -30,6 +30,7 @@ import java.lang.reflect.Modifier; import java.util.ArrayList; import java.util.Comparator; import java.util.List; +import java.util.Objects; import java.util.Set; import java.util.TreeSet; @@ -345,7 +346,7 @@ class ExtendedBeanInfo implements BeanInfo { @Override public int hashCode() { - return (ObjectUtils.nullSafeHashCode(getReadMethod()) * 29 + ObjectUtils.nullSafeHashCode(getWriteMethod())); + return Objects.hash(getReadMethod(), getWriteMethod()); } @Override @@ -500,11 +501,8 @@ class ExtendedBeanInfo implements BeanInfo { @Override public int hashCode() { - int hashCode = ObjectUtils.nullSafeHashCode(getReadMethod()); - hashCode = 29 * hashCode + ObjectUtils.nullSafeHashCode(getWriteMethod()); - hashCode = 29 * hashCode + ObjectUtils.nullSafeHashCode(getIndexedReadMethod()); - hashCode = 29 * hashCode + ObjectUtils.nullSafeHashCode(getIndexedWriteMethod()); - return hashCode; + return Objects.hash(getReadMethod(), getWriteMethod(), + getIndexedReadMethod(), getIndexedWriteMethod()); } @Override diff --git a/spring-beans/src/main/java/org/springframework/beans/GenericTypeAwarePropertyDescriptor.java b/spring-beans/src/main/java/org/springframework/beans/GenericTypeAwarePropertyDescriptor.java index 017b7bb12c..b7d4c18a43 100644 --- a/spring-beans/src/main/java/org/springframework/beans/GenericTypeAwarePropertyDescriptor.java +++ b/spring-beans/src/main/java/org/springframework/beans/GenericTypeAwarePropertyDescriptor.java @@ -20,6 +20,7 @@ import java.beans.IntrospectionException; import java.beans.PropertyDescriptor; import java.lang.reflect.Method; import java.util.HashSet; +import java.util.Objects; import java.util.Set; import org.apache.commons.logging.LogFactory; @@ -30,7 +31,6 @@ import org.springframework.core.MethodParameter; import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.ClassUtils; -import org.springframework.util.ObjectUtils; import org.springframework.util.StringUtils; /** @@ -172,10 +172,7 @@ final class GenericTypeAwarePropertyDescriptor extends PropertyDescriptor { @Override public int hashCode() { - int hashCode = getBeanClass().hashCode(); - hashCode = 29 * hashCode + ObjectUtils.nullSafeHashCode(getReadMethod()); - hashCode = 29 * hashCode + ObjectUtils.nullSafeHashCode(getWriteMethod()); - return hashCode; + return Objects.hash(getBeanClass(), getReadMethod(), getWriteMethod()); } } diff --git a/spring-beans/src/main/java/org/springframework/beans/PropertyValue.java b/spring-beans/src/main/java/org/springframework/beans/PropertyValue.java index b9f374e93f..00f567b0f6 100644 --- a/spring-beans/src/main/java/org/springframework/beans/PropertyValue.java +++ b/spring-beans/src/main/java/org/springframework/beans/PropertyValue.java @@ -197,7 +197,7 @@ public class PropertyValue extends BeanMetadataAttributeAccessor implements Seri @Override public int hashCode() { - return this.name.hashCode() * 29 + ObjectUtils.nullSafeHashCode(this.value); + return ObjectUtils.nullSafeHash(this.name, this.value); } @Override diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/InjectionPoint.java b/spring-beans/src/main/java/org/springframework/beans/factory/InjectionPoint.java index eed896e1b4..0a4731f904 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/InjectionPoint.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/InjectionPoint.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2022 the original author or authors. + * Copyright 2002-2023 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,6 +20,7 @@ import java.lang.annotation.Annotation; import java.lang.reflect.AnnotatedElement; import java.lang.reflect.Field; import java.lang.reflect.Member; +import java.util.Objects; import org.springframework.core.MethodParameter; import org.springframework.lang.Nullable; @@ -190,7 +191,7 @@ public class InjectionPoint { @Override public int hashCode() { - return (this.field != null ? this.field.hashCode() : ObjectUtils.nullSafeHashCode(this.methodParameter)); + return Objects.hash(this.field, this.methodParameter); } @Override diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/config/BeanDefinitionHolder.java b/spring-beans/src/main/java/org/springframework/beans/factory/config/BeanDefinitionHolder.java index 36a56cae9d..92da17f355 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/config/BeanDefinitionHolder.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/config/BeanDefinitionHolder.java @@ -173,10 +173,8 @@ public class BeanDefinitionHolder implements BeanMetadataElement { @Override public int hashCode() { - int hashCode = this.beanDefinition.hashCode(); - hashCode = 29 * hashCode + this.beanName.hashCode(); - hashCode = 29 * hashCode + ObjectUtils.nullSafeHashCode(this.aliases); - return hashCode; + return ObjectUtils.nullSafeHash(this.beanDefinition, this.beanName, + this.aliases); } } diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/config/ConstructorArgumentValues.java b/spring-beans/src/main/java/org/springframework/beans/factory/config/ConstructorArgumentValues.java index 7c240653eb..175f5a4c0b 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/config/ConstructorArgumentValues.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/config/ConstructorArgumentValues.java @@ -606,7 +606,7 @@ public class ConstructorArgumentValues { * same content to reside in the same Set. */ private int contentHashCode() { - return ObjectUtils.nullSafeHashCode(this.value) * 29 + ObjectUtils.nullSafeHashCode(this.type); + return ObjectUtils.nullSafeHash(this.value, this.type); } /** diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/config/TypedStringValue.java b/spring-beans/src/main/java/org/springframework/beans/factory/config/TypedStringValue.java index 79b91cfe10..1471f69200 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/config/TypedStringValue.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/config/TypedStringValue.java @@ -223,7 +223,7 @@ public class TypedStringValue implements BeanMetadataElement { @Override public int hashCode() { - return ObjectUtils.nullSafeHashCode(this.value) * 29 + ObjectUtils.nullSafeHashCode(this.targetType); + return ObjectUtils.nullSafeHash(this.value, this.targetType); } @Override diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/support/MethodOverride.java b/spring-beans/src/main/java/org/springframework/beans/factory/support/MethodOverride.java index e0880d60cb..d250320dde 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/support/MethodOverride.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/support/MethodOverride.java @@ -113,9 +113,7 @@ public abstract class MethodOverride implements BeanMetadataElement { @Override public int hashCode() { - int hashCode = ObjectUtils.nullSafeHashCode(this.methodName); - hashCode = 29 * hashCode + ObjectUtils.nullSafeHashCode(this.source); - return hashCode; + return ObjectUtils.nullSafeHash(this.methodName, this.source); } } diff --git a/spring-context-support/src/main/java/org/springframework/mail/SimpleMailMessage.java b/spring-context-support/src/main/java/org/springframework/mail/SimpleMailMessage.java index 81657e9045..d86db63adb 100644 --- a/spring-context-support/src/main/java/org/springframework/mail/SimpleMailMessage.java +++ b/spring-context-support/src/main/java/org/springframework/mail/SimpleMailMessage.java @@ -236,14 +236,8 @@ public class SimpleMailMessage implements MailMessage, Serializable { @Override public int hashCode() { - int hashCode = ObjectUtils.nullSafeHashCode(this.from); - hashCode = 29 * hashCode + ObjectUtils.nullSafeHashCode(this.replyTo); - hashCode = 29 * hashCode + ObjectUtils.nullSafeHashCode(this.to); - hashCode = 29 * hashCode + ObjectUtils.nullSafeHashCode(this.cc); - hashCode = 29 * hashCode + ObjectUtils.nullSafeHashCode(this.bcc); - hashCode = 29 * hashCode + ObjectUtils.nullSafeHashCode(this.sentDate); - hashCode = 29 * hashCode + ObjectUtils.nullSafeHashCode(this.subject); - return hashCode; + return ObjectUtils.nullSafeHash(this.from, this.replyTo, this.to, this.cc, + this.bcc, this.sentDate, this.subject); } @Override diff --git a/spring-context/src/main/java/org/springframework/context/event/AbstractApplicationEventMulticaster.java b/spring-context/src/main/java/org/springframework/context/event/AbstractApplicationEventMulticaster.java index 43b6ddd89d..f22e0ceb72 100644 --- a/spring-context/src/main/java/org/springframework/context/event/AbstractApplicationEventMulticaster.java +++ b/spring-context/src/main/java/org/springframework/context/event/AbstractApplicationEventMulticaster.java @@ -21,6 +21,7 @@ import java.util.Collection; import java.util.LinkedHashSet; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.function.Predicate; @@ -404,7 +405,7 @@ public abstract class AbstractApplicationEventMulticaster @Override public int hashCode() { - return this.eventType.hashCode() * 29 + ObjectUtils.nullSafeHashCode(this.sourceType); + return Objects.hash(this.eventType, this.sourceType); } @Override diff --git a/spring-context/src/main/java/org/springframework/context/support/ApplicationListenerDetector.java b/spring-context/src/main/java/org/springframework/context/support/ApplicationListenerDetector.java index 7589409bde..342839892a 100644 --- a/spring-context/src/main/java/org/springframework/context/support/ApplicationListenerDetector.java +++ b/spring-context/src/main/java/org/springframework/context/support/ApplicationListenerDetector.java @@ -17,6 +17,7 @@ package org.springframework.context.support; import java.util.Map; +import java.util.Objects; import java.util.concurrent.ConcurrentHashMap; import org.apache.commons.logging.Log; @@ -28,7 +29,6 @@ import org.springframework.beans.factory.support.RootBeanDefinition; import org.springframework.context.ApplicationListener; import org.springframework.context.event.ApplicationEventMulticaster; import org.springframework.lang.Nullable; -import org.springframework.util.ObjectUtils; /** * {@code BeanPostProcessor} that detects beans which implement the {@code ApplicationListener} @@ -120,7 +120,7 @@ class ApplicationListenerDetector implements DestructionAwareBeanPostProcessor, @Override public int hashCode() { - return ObjectUtils.nullSafeHashCode(this.applicationContext); + return Objects.hashCode(this.applicationContext); } } diff --git a/spring-context/src/main/java/org/springframework/context/support/DefaultMessageSourceResolvable.java b/spring-context/src/main/java/org/springframework/context/support/DefaultMessageSourceResolvable.java index 281b8e7986..df09bc8957 100644 --- a/spring-context/src/main/java/org/springframework/context/support/DefaultMessageSourceResolvable.java +++ b/spring-context/src/main/java/org/springframework/context/support/DefaultMessageSourceResolvable.java @@ -179,10 +179,7 @@ public class DefaultMessageSourceResolvable implements MessageSourceResolvable, @Override public int hashCode() { - int hashCode = ObjectUtils.nullSafeHashCode(getCodes()); - hashCode = 29 * hashCode + ObjectUtils.nullSafeHashCode(getArguments()); - hashCode = 29 * hashCode + ObjectUtils.nullSafeHashCode(getDefaultMessage()); - return hashCode; + return ObjectUtils.nullSafeHash(getCode(), getArguments(), getDefaultMessage()); } } diff --git a/spring-context/src/main/java/org/springframework/jmx/support/NotificationListenerHolder.java b/spring-context/src/main/java/org/springframework/jmx/support/NotificationListenerHolder.java index 6866af0371..9244be32ce 100644 --- a/spring-context/src/main/java/org/springframework/jmx/support/NotificationListenerHolder.java +++ b/spring-context/src/main/java/org/springframework/jmx/support/NotificationListenerHolder.java @@ -167,11 +167,8 @@ public class NotificationListenerHolder { @Override public int hashCode() { - int hashCode = ObjectUtils.nullSafeHashCode(this.notificationListener); - hashCode = 29 * hashCode + ObjectUtils.nullSafeHashCode(this.notificationFilter); - hashCode = 29 * hashCode + ObjectUtils.nullSafeHashCode(this.handback); - hashCode = 29 * hashCode + ObjectUtils.nullSafeHashCode(this.mappedObjectNames); - return hashCode; + return ObjectUtils.nullSafeHash(this.notificationListener, this.notificationFilter, + this.handback, this.mappedObjectNames); } } diff --git a/spring-context/src/testFixtures/java/org/springframework/context/testfixture/cache/beans/TestEntity.java b/spring-context/src/testFixtures/java/org/springframework/context/testfixture/cache/beans/TestEntity.java index 7a9d36fb41..4fd7e9c045 100644 --- a/spring-context/src/testFixtures/java/org/springframework/context/testfixture/cache/beans/TestEntity.java +++ b/spring-context/src/testFixtures/java/org/springframework/context/testfixture/cache/beans/TestEntity.java @@ -16,6 +16,8 @@ package org.springframework.context.testfixture.cache.beans; +import java.util.Objects; + import org.springframework.lang.Nullable; import org.springframework.util.ObjectUtils; @@ -38,7 +40,7 @@ public class TestEntity { @Override public int hashCode() { - return ObjectUtils.nullSafeHashCode(this.id); + return Objects.hashCode(this.id); } @Override diff --git a/spring-core/src/main/java/org/springframework/core/annotation/RepeatableContainers.java b/spring-core/src/main/java/org/springframework/core/annotation/RepeatableContainers.java index 7d9f4b135c..581ffeb9c8 100644 --- a/spring-core/src/main/java/org/springframework/core/annotation/RepeatableContainers.java +++ b/spring-core/src/main/java/org/springframework/core/annotation/RepeatableContainers.java @@ -20,6 +20,7 @@ import java.lang.annotation.Annotation; import java.lang.annotation.Repeatable; import java.lang.reflect.Method; import java.util.Map; +import java.util.Objects; import org.springframework.lang.Nullable; import org.springframework.util.Assert; @@ -91,7 +92,7 @@ public abstract class RepeatableContainers { @Override public int hashCode() { - return ObjectUtils.nullSafeHashCode(this.parent); + return Objects.hashCode(this.parent); } diff --git a/spring-core/src/main/java/org/springframework/core/convert/Property.java b/spring-core/src/main/java/org/springframework/core/convert/Property.java index 1e774106cd..e0b601cdd4 100644 --- a/spring-core/src/main/java/org/springframework/core/convert/Property.java +++ b/spring-core/src/main/java/org/springframework/core/convert/Property.java @@ -22,6 +22,7 @@ import java.lang.reflect.Field; import java.lang.reflect.Method; import java.util.LinkedHashMap; import java.util.Map; +import java.util.Objects; import org.springframework.core.MethodParameter; import org.springframework.lang.Nullable; @@ -269,7 +270,7 @@ public final class Property { @Override public int hashCode() { - return (ObjectUtils.nullSafeHashCode(this.objectType) * 31 + ObjectUtils.nullSafeHashCode(this.name)); + return Objects.hash(this.objectType, this.name); } } diff --git a/spring-core/src/main/java/org/springframework/core/env/PropertySource.java b/spring-core/src/main/java/org/springframework/core/env/PropertySource.java index 64ad2c0d92..3135f07220 100644 --- a/spring-core/src/main/java/org/springframework/core/env/PropertySource.java +++ b/spring-core/src/main/java/org/springframework/core/env/PropertySource.java @@ -16,6 +16,8 @@ package org.springframework.core.env; +import java.util.Objects; + import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -147,7 +149,7 @@ public abstract class PropertySource { */ @Override public int hashCode() { - return ObjectUtils.nullSafeHashCode(getName()); + return Objects.hashCode(getName()); } /** diff --git a/spring-core/src/main/java/org/springframework/util/ObjectUtils.java b/spring-core/src/main/java/org/springframework/util/ObjectUtils.java index db8aa1ebeb..493ae8d6e6 100644 --- a/spring-core/src/main/java/org/springframework/util/ObjectUtils.java +++ b/spring-core/src/main/java/org/springframework/util/ObjectUtils.java @@ -22,6 +22,7 @@ import java.time.ZoneId; import java.util.Arrays; import java.util.Collection; import java.util.Map; +import java.util.Objects; import java.util.Optional; import java.util.StringJoiner; import java.util.TimeZone; @@ -390,21 +391,32 @@ public abstract class ObjectUtils { } /** - * Return as hash code for the given object; typically the value of + * Return a hash code for the given elements, delegating to + * {@link #nullSafeHashCode(Object)} for each element. Contrary + * to {@link Objects#hash(Object...)}, this method handle an + * element that is an array. + * @param elements the elements to be hashed + * @return a hash value of the elements + * @since 6.1 + */ + public static int nullSafeHash(@Nullable Object... elements) { + if (elements == null) { + return 0; + } + int result = 1; + for (Object element : elements) { + result = 31 * result + nullSafeHashCode(element); + } + return result; + } + + /** + * Return a hash code for the given object; typically the value of * {@code Object#hashCode()}}. If the object is an array, - * this method will delegate to any of the {@code nullSafeHashCode} - * methods for arrays in this class. If the object is {@code null}, - * this method returns 0. + * this method will delegate to any of the {@code Arrays#hasCode} + * methods. If the object is {@code null}, this method returns 0. * @see Object#hashCode() - * @see #nullSafeHashCode(Object[]) - * @see #nullSafeHashCode(boolean[]) - * @see #nullSafeHashCode(byte[]) - * @see #nullSafeHashCode(char[]) - * @see #nullSafeHashCode(double[]) - * @see #nullSafeHashCode(float[]) - * @see #nullSafeHashCode(int[]) - * @see #nullSafeHashCode(long[]) - * @see #nullSafeHashCode(short[]) + * @see Arrays */ public static int nullSafeHashCode(@Nullable Object obj) { if (obj == null) { @@ -412,31 +424,31 @@ public abstract class ObjectUtils { } if (obj.getClass().isArray()) { if (obj instanceof Object[] objects) { - return nullSafeHashCode(objects); + return Arrays.hashCode(objects); } if (obj instanceof boolean[] booleans) { - return nullSafeHashCode(booleans); + return Arrays.hashCode(booleans); } if (obj instanceof byte[] bytes) { - return nullSafeHashCode(bytes); + return Arrays.hashCode(bytes); } if (obj instanceof char[] chars) { - return nullSafeHashCode(chars); + return Arrays.hashCode(chars); } if (obj instanceof double[] doubles) { - return nullSafeHashCode(doubles); + return Arrays.hashCode(doubles); } if (obj instanceof float[] floats) { - return nullSafeHashCode(floats); + return Arrays.hashCode(floats); } if (obj instanceof int[] ints) { - return nullSafeHashCode(ints); + return Arrays.hashCode(ints); } if (obj instanceof long[] longs) { - return nullSafeHashCode(longs); + return Arrays.hashCode(longs); } if (obj instanceof short[] shorts) { - return nullSafeHashCode(shorts); + return Arrays.hashCode(shorts); } } return obj.hashCode(); @@ -445,136 +457,91 @@ public abstract class ObjectUtils { /** * Return a hash code based on the contents of the specified array. * If {@code array} is {@code null}, this method returns 0. + * @deprecated as of 6.1 in favor of {@link Arrays#hashCode(Object[])} */ + @Deprecated(since = "6.1") public static int nullSafeHashCode(@Nullable Object[] array) { - if (array == null) { - return 0; - } - int hash = INITIAL_HASH; - for (Object element : array) { - hash = MULTIPLIER * hash + nullSafeHashCode(element); - } - return hash; + return Arrays.hashCode(array); } /** * Return a hash code based on the contents of the specified array. * If {@code array} is {@code null}, this method returns 0. + * @deprecated as of 6.1 in favor of {@link Arrays#hashCode(boolean[])} */ + @Deprecated(since = "6.1") public static int nullSafeHashCode(@Nullable boolean[] array) { - if (array == null) { - return 0; - } - int hash = INITIAL_HASH; - for (boolean element : array) { - hash = MULTIPLIER * hash + Boolean.hashCode(element); - } - return hash; + return Arrays.hashCode(array); } /** * Return a hash code based on the contents of the specified array. * If {@code array} is {@code null}, this method returns 0. + * @deprecated as of 6.1 in favor of {@link Arrays#hashCode(byte[])} */ + @Deprecated(since = "6.1") public static int nullSafeHashCode(@Nullable byte[] array) { - if (array == null) { - return 0; - } - int hash = INITIAL_HASH; - for (byte element : array) { - hash = MULTIPLIER * hash + element; - } - return hash; + return Arrays.hashCode(array); } /** * Return a hash code based on the contents of the specified array. * If {@code array} is {@code null}, this method returns 0. + * @deprecated as of 6.1 in favor of {@link Arrays#hashCode(char[])} */ + @Deprecated(since = "6.1") public static int nullSafeHashCode(@Nullable char[] array) { - if (array == null) { - return 0; - } - int hash = INITIAL_HASH; - for (char element : array) { - hash = MULTIPLIER * hash + element; - } - return hash; + return Arrays.hashCode(array); } /** * Return a hash code based on the contents of the specified array. * If {@code array} is {@code null}, this method returns 0. + * @deprecated as of 6.1 in favor of {@link Arrays#hashCode(double[])} */ + @Deprecated(since = "6.1") public static int nullSafeHashCode(@Nullable double[] array) { - if (array == null) { - return 0; - } - int hash = INITIAL_HASH; - for (double element : array) { - hash = MULTIPLIER * hash + Double.hashCode(element); - } - return hash; + return Arrays.hashCode(array); } /** * Return a hash code based on the contents of the specified array. * If {@code array} is {@code null}, this method returns 0. + * @deprecated as of 6.1 in favor of {@link Arrays#hashCode(float[])} */ + @Deprecated(since = "6.1") public static int nullSafeHashCode(@Nullable float[] array) { - if (array == null) { - return 0; - } - int hash = INITIAL_HASH; - for (float element : array) { - hash = MULTIPLIER * hash + Float.hashCode(element); - } - return hash; + return Arrays.hashCode(array); } /** * Return a hash code based on the contents of the specified array. * If {@code array} is {@code null}, this method returns 0. + * @deprecated as of 6.1 in favor of {@link Arrays#hashCode(int[])} */ + @Deprecated(since = "6.1") public static int nullSafeHashCode(@Nullable int[] array) { - if (array == null) { - return 0; - } - int hash = INITIAL_HASH; - for (int element : array) { - hash = MULTIPLIER * hash + element; - } - return hash; + return Arrays.hashCode(array); } /** * Return a hash code based on the contents of the specified array. * If {@code array} is {@code null}, this method returns 0. + * @deprecated as of 6.1 in favor of {@link Arrays#hashCode(long[])} */ + @Deprecated(since = "6.1") public static int nullSafeHashCode(@Nullable long[] array) { - if (array == null) { - return 0; - } - int hash = INITIAL_HASH; - for (long element : array) { - hash = MULTIPLIER * hash + Long.hashCode(element); - } - return hash; + return Arrays.hashCode(array); } /** * Return a hash code based on the contents of the specified array. * If {@code array} is {@code null}, this method returns 0. + * @deprecated as of 6.1 in favor of {@link Arrays#hashCode(short[])} */ + @Deprecated(since = "6.1") public static int nullSafeHashCode(@Nullable short[] array) { - if (array == null) { - return 0; - } - int hash = INITIAL_HASH; - for (short element : array) { - hash = MULTIPLIER * hash + element; - } - return hash; + return Arrays.hashCode(array); } diff --git a/spring-core/src/test/java/org/springframework/util/ObjectUtilsTests.java b/spring-core/src/test/java/org/springframework/util/ObjectUtilsTests.java index 8090c4be82..99388b1b8f 100644 --- a/spring-core/src/test/java/org/springframework/util/ObjectUtilsTests.java +++ b/spring-core/src/test/java/org/springframework/util/ObjectUtilsTests.java @@ -30,6 +30,7 @@ import java.nio.file.Path; import java.sql.SQLException; import java.time.LocalDate; import java.time.ZoneId; +import java.util.Arrays; import java.util.Collections; import java.util.Currency; import java.util.Date; @@ -38,6 +39,7 @@ import java.util.HashSet; import java.util.List; import java.util.Locale; import java.util.Map; +import java.util.Objects; import java.util.Optional; import java.util.Set; import java.util.TimeZone; @@ -379,119 +381,197 @@ class ObjectUtilsTests { } @Test - void nullSafeHashCodeWithBooleanArray() { - int expected = 31 * 7 + Boolean.TRUE.hashCode(); - expected = 31 * expected + Boolean.FALSE.hashCode(); + void nullSafeHashWithNull() { + assertThat(ObjectUtils.nullSafeHash((Object[]) null)).isEqualTo(0); + } + @Test + void nullSafeHashWithIntermediateNullElements() { + assertThat(ObjectUtils.nullSafeHash(3, null, 5)).isEqualTo(Objects.hash(3, null, 5)); + } + + @Test + @Deprecated + void nullSafeHashCodeWithNullBooleanArray() { + boolean[] array = null; + assertThat(ObjectUtils.nullSafeHashCode(array)).isEqualTo(0); + } + + @Test + @Deprecated + void nullSafeHashCodeWithBooleanArray() { boolean[] array = {true, false}; int actual = ObjectUtils.nullSafeHashCode(array); - - assertThat(actual).isEqualTo(expected); + assertThat(actual).isEqualTo(Arrays.hashCode(array)); } @Test - void nullSafeHashCodeWithBooleanArrayEqualToNull() { - assertThat(ObjectUtils.nullSafeHashCode((boolean[]) null)).isEqualTo(0); + @Deprecated + void nullSafeHashCodeWithObjectBeingBooleanArray() { + Object array = new boolean[] {true, false}; + int expected = ObjectUtils.nullSafeHashCode((boolean[]) array); + assertEqualHashCodes(expected, array); } @Test + @Deprecated + void nullSafeHashCodeWithNullByteArray() { + byte[] array = null; + assertThat(ObjectUtils.nullSafeHashCode(array)).isEqualTo(0); + } + + @Test + @Deprecated void nullSafeHashCodeWithByteArray() { - int expected = 31 * 7 + 8; - expected = 31 * expected + 10; - byte[] array = {8, 10}; int actual = ObjectUtils.nullSafeHashCode(array); - - assertThat(actual).isEqualTo(expected); + assertThat(actual).isEqualTo(Arrays.hashCode(array)); } @Test - void nullSafeHashCodeWithByteArrayEqualToNull() { - assertThat(ObjectUtils.nullSafeHashCode((byte[]) null)).isEqualTo(0); + @Deprecated + void nullSafeHashCodeWithObjectBeingByteArray() { + Object array = new byte[] {6, 39}; + int expected = ObjectUtils.nullSafeHashCode((byte[]) array); + assertEqualHashCodes(expected, array); } @Test + @Deprecated + void nullSafeHashCodeWithNullCharArray() { + char[] array = null; + assertThat(ObjectUtils.nullSafeHashCode(array)).isEqualTo(0); + } + + @Test + @Deprecated void nullSafeHashCodeWithCharArray() { - int expected = 31 * 7 + 'a'; - expected = 31 * expected + 'E'; - char[] array = {'a', 'E'}; int actual = ObjectUtils.nullSafeHashCode(array); - - assertThat(actual).isEqualTo(expected); + assertThat(actual).isEqualTo(Arrays.hashCode(array)); } @Test - void nullSafeHashCodeWithCharArrayEqualToNull() { - assertThat(ObjectUtils.nullSafeHashCode((char[]) null)).isEqualTo(0); + @Deprecated + void nullSafeHashCodeWithObjectBeingCharArray() { + Object array = new char[] {'l', 'M'}; + int expected = ObjectUtils.nullSafeHashCode((char[]) array); + assertEqualHashCodes(expected, array); } @Test + @Deprecated + void nullSafeHashCodeWithNullDoubleArray() { + double[] array = null; + assertThat(ObjectUtils.nullSafeHashCode(array)).isEqualTo(0); + } + + @Test + @Deprecated void nullSafeHashCodeWithDoubleArray() { - long bits = Double.doubleToLongBits(8449.65); - int expected = 31 * 7 + (int) (bits ^ (bits >>> 32)); - bits = Double.doubleToLongBits(9944.923); - expected = 31 * expected + (int) (bits ^ (bits >>> 32)); - double[] array = {8449.65, 9944.923}; int actual = ObjectUtils.nullSafeHashCode(array); - - assertThat(actual).isEqualTo(expected); + assertThat(actual).isEqualTo(Arrays.hashCode(array)); } @Test - void nullSafeHashCodeWithDoubleArrayEqualToNull() { - assertThat(ObjectUtils.nullSafeHashCode((double[]) null)).isEqualTo(0); + @Deprecated + void nullSafeHashCodeWithObjectBeingDoubleArray() { + Object array = new double[] {68930.993, 9022.009}; + int expected = ObjectUtils.nullSafeHashCode((double[]) array); + assertEqualHashCodes(expected, array); } @Test + @Deprecated + void nullSafeHashCodeWithNullFloatArray() { + float[] array = null; + assertThat(ObjectUtils.nullSafeHashCode(array)).isEqualTo(0); + } + + @Test + @Deprecated void nullSafeHashCodeWithFloatArray() { - int expected = 31 * 7 + Float.floatToIntBits(9.6f); - expected = 31 * expected + Float.floatToIntBits(7.4f); - float[] array = {9.6f, 7.4f}; int actual = ObjectUtils.nullSafeHashCode(array); - - assertThat(actual).isEqualTo(expected); + assertThat(actual).isEqualTo(Arrays.hashCode(array)); } @Test - void nullSafeHashCodeWithFloatArrayEqualToNull() { - assertThat(ObjectUtils.nullSafeHashCode((float[]) null)).isEqualTo(0); + @Deprecated + void nullSafeHashCodeWithObjectBeingFloatArray() { + Object array = new float[] {9.9f, 9.54f}; + int expected = ObjectUtils.nullSafeHashCode((float[]) array); + assertEqualHashCodes(expected, array); } @Test + @Deprecated + void nullSafeHashCodeWithNullIntArray() { + int[] array = null; + assertThat(ObjectUtils.nullSafeHashCode(array)).isEqualTo(0); + } + + @Test + @Deprecated void nullSafeHashCodeWithIntArray() { - int expected = 31 * 7 + 884; - expected = 31 * expected + 340; - int[] array = {884, 340}; int actual = ObjectUtils.nullSafeHashCode(array); - - assertThat(actual).isEqualTo(expected); + assertThat(actual).isEqualTo(Arrays.hashCode(array)); } @Test - void nullSafeHashCodeWithIntArrayEqualToNull() { - assertThat(ObjectUtils.nullSafeHashCode((int[]) null)).isEqualTo(0); + @Deprecated + void nullSafeHashCodeWithObjectBeingIntArray() { + Object array = new int[] {89, 32}; + int expected = ObjectUtils.nullSafeHashCode((int[]) array); + assertEqualHashCodes(expected, array); } @Test + @Deprecated + void nullSafeHashCodeWithNullLongArray() { + long[] array = null; + assertThat(ObjectUtils.nullSafeHashCode(array)).isEqualTo(0); + } + + @Test + @Deprecated void nullSafeHashCodeWithLongArray() { - long lng = 7993L; - int expected = 31 * 7 + (int) (lng ^ (lng >>> 32)); - lng = 84320L; - expected = 31 * expected + (int) (lng ^ (lng >>> 32)); - long[] array = {7993L, 84320L}; int actual = ObjectUtils.nullSafeHashCode(array); - - assertThat(actual).isEqualTo(expected); + assertThat(actual).isEqualTo(Arrays.hashCode(array)); } @Test - void nullSafeHashCodeWithLongArrayEqualToNull() { - assertThat(ObjectUtils.nullSafeHashCode((long[]) null)).isEqualTo(0); + @Deprecated + void nullSafeHashCodeWithObjectBeingLongArray() { + Object array = new long[] {4389, 320}; + int expected = ObjectUtils.nullSafeHashCode((long[]) array); + assertEqualHashCodes(expected, array); + } + + @Test + @Deprecated + void nullSafeHashCodeWithNullShortArray() { + short[] array = null; + assertThat(ObjectUtils.nullSafeHashCode(array)).isEqualTo(0); + } + + @Test + @Deprecated + void nullSafeHashCodeWithShortArray() { + short[] array = {4, 25}; + int actual = ObjectUtils.nullSafeHashCode(array); + assertThat(actual).isEqualTo(Arrays.hashCode(array)); + } + + @Test + @Deprecated + void nullSafeHashCodeWithObjectBeingShortArray() { + Object array = new short[] {5, 3}; + int expected = ObjectUtils.nullSafeHashCode((short[]) array); + assertEqualHashCodes(expected, array); } @Test @@ -501,71 +581,21 @@ class ObjectUtilsTests { } @Test + @Deprecated void nullSafeHashCodeWithObjectArray() { - int expected = 31 * 7 + "Leia".hashCode(); - expected = 31 * expected + "Han".hashCode(); - Object[] array = {"Leia", "Han"}; int actual = ObjectUtils.nullSafeHashCode(array); - - assertThat(actual).isEqualTo(expected); + assertThat(actual).isEqualTo(Arrays.hashCode(array)); } @Test + @Deprecated void nullSafeHashCodeWithObjectArrayEqualToNull() { assertThat(ObjectUtils.nullSafeHashCode((Object[]) null)).isEqualTo(0); } @Test - void nullSafeHashCodeWithObjectBeingBooleanArray() { - Object array = new boolean[] {true, false}; - int expected = ObjectUtils.nullSafeHashCode((boolean[]) array); - assertEqualHashCodes(expected, array); - } - - @Test - void nullSafeHashCodeWithObjectBeingByteArray() { - Object array = new byte[] {6, 39}; - int expected = ObjectUtils.nullSafeHashCode((byte[]) array); - assertEqualHashCodes(expected, array); - } - - @Test - void nullSafeHashCodeWithObjectBeingCharArray() { - Object array = new char[] {'l', 'M'}; - int expected = ObjectUtils.nullSafeHashCode((char[]) array); - assertEqualHashCodes(expected, array); - } - - @Test - void nullSafeHashCodeWithObjectBeingDoubleArray() { - Object array = new double[] {68930.993, 9022.009}; - int expected = ObjectUtils.nullSafeHashCode((double[]) array); - assertEqualHashCodes(expected, array); - } - - @Test - void nullSafeHashCodeWithObjectBeingFloatArray() { - Object array = new float[] {9.9f, 9.54f}; - int expected = ObjectUtils.nullSafeHashCode((float[]) array); - assertEqualHashCodes(expected, array); - } - - @Test - void nullSafeHashCodeWithObjectBeingIntArray() { - Object array = new int[] {89, 32}; - int expected = ObjectUtils.nullSafeHashCode((int[]) array); - assertEqualHashCodes(expected, array); - } - - @Test - void nullSafeHashCodeWithObjectBeingLongArray() { - Object array = new long[] {4389, 320}; - int expected = ObjectUtils.nullSafeHashCode((long[]) array); - assertEqualHashCodes(expected, array); - } - - @Test + @Deprecated void nullSafeHashCodeWithObjectBeingObjectArray() { Object array = new Object[] {"Luke", "Anakin"}; int expected = ObjectUtils.nullSafeHashCode((Object[]) array); @@ -573,31 +603,10 @@ class ObjectUtilsTests { } @Test - void nullSafeHashCodeWithObjectBeingShortArray() { - Object array = new short[] {5, 3}; - int expected = ObjectUtils.nullSafeHashCode((short[]) array); - assertEqualHashCodes(expected, array); - } - - @Test + @Deprecated void nullSafeHashCodeWithObjectEqualToNull() { - assertThat(ObjectUtils.nullSafeHashCode((Object) null)).isEqualTo(0); - } - - @Test - void nullSafeHashCodeWithShortArray() { - int expected = 31 * 7 + 70; - expected = 31 * expected + 8; - - short[] array = {70, 8}; - int actual = ObjectUtils.nullSafeHashCode(array); - - assertThat(actual).isEqualTo(expected); - } - - @Test - void nullSafeHashCodeWithShortArrayEqualToNull() { - assertThat(ObjectUtils.nullSafeHashCode((short[]) null)).isEqualTo(0); + Object[] array = null; + assertThat(ObjectUtils.nullSafeHashCode(array)).isEqualTo(0); } @Test 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 6973f11b85..4dad562b31 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 @@ -23,6 +23,7 @@ import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.Map; +import java.util.Objects; import java.util.Set; import java.util.UUID; import java.util.concurrent.ConcurrentHashMap; @@ -539,7 +540,7 @@ public class MultiServerUserRegistry implements SimpUserRegistry, SmartApplicati @Override public int hashCode() { - return getId().hashCode() * 31 + ObjectUtils.nullSafeHashCode(getSession()); + return Objects.hash(getId(), getSession()); } @Override diff --git a/spring-messaging/src/main/java/org/springframework/messaging/support/GenericMessage.java b/spring-messaging/src/main/java/org/springframework/messaging/support/GenericMessage.java index b81401a94b..72b06f560a 100644 --- a/spring-messaging/src/main/java/org/springframework/messaging/support/GenericMessage.java +++ b/spring-messaging/src/main/java/org/springframework/messaging/support/GenericMessage.java @@ -98,7 +98,7 @@ public class GenericMessage implements Message, Serializable { @Override public int hashCode() { // Using nullSafeHashCode for proper array hashCode handling - return ObjectUtils.nullSafeHashCode(this.payload) * 23 + this.headers.hashCode(); + return ObjectUtils.nullSafeHash(this.payload, this.headers); } @Override diff --git a/spring-messaging/src/test/java/org/springframework/messaging/simp/user/TestSimpSubscription.java b/spring-messaging/src/test/java/org/springframework/messaging/simp/user/TestSimpSubscription.java index 1cc9ffb576..bad87cf42c 100644 --- a/spring-messaging/src/test/java/org/springframework/messaging/simp/user/TestSimpSubscription.java +++ b/spring-messaging/src/test/java/org/springframework/messaging/simp/user/TestSimpSubscription.java @@ -16,6 +16,8 @@ package org.springframework.messaging.simp.user; +import java.util.Objects; + import org.springframework.lang.Nullable; import org.springframework.util.ObjectUtils; @@ -66,7 +68,7 @@ public class TestSimpSubscription implements SimpSubscription { @Override public int hashCode() { - return this.id.hashCode() * 31 + ObjectUtils.nullSafeHashCode(getSession()); + return Objects.hash(this.id, getSession()); } @Override diff --git a/spring-r2dbc/src/main/java/org/springframework/r2dbc/core/Parameter.java b/spring-r2dbc/src/main/java/org/springframework/r2dbc/core/Parameter.java index 453415b659..7d0d482fac 100644 --- a/spring-r2dbc/src/main/java/org/springframework/r2dbc/core/Parameter.java +++ b/spring-r2dbc/src/main/java/org/springframework/r2dbc/core/Parameter.java @@ -117,7 +117,7 @@ public final class Parameter { @Override public int hashCode() { - return ObjectUtils.nullSafeHashCode(this.value) + ObjectUtils.nullSafeHashCode(this.type); + return ObjectUtils.nullSafeHash(this.value, this.type); } @Override diff --git a/spring-web/src/main/java/org/springframework/http/ContentDisposition.java b/spring-web/src/main/java/org/springframework/http/ContentDisposition.java index 5600bb16e4..e2f1cdecb6 100644 --- a/spring-web/src/main/java/org/springframework/http/ContentDisposition.java +++ b/spring-web/src/main/java/org/springframework/http/ContentDisposition.java @@ -240,15 +240,8 @@ public final class ContentDisposition { @Override public int hashCode() { - int result = ObjectUtils.nullSafeHashCode(this.type); - result = 31 * result + ObjectUtils.nullSafeHashCode(this.name); - result = 31 * result + ObjectUtils.nullSafeHashCode(this.filename); - result = 31 * result + ObjectUtils.nullSafeHashCode(this.charset); - result = 31 * result + ObjectUtils.nullSafeHashCode(this.size); - result = 31 * result + ObjectUtils.nullSafeHashCode(this.creationDate); - result = 31 * result + ObjectUtils.nullSafeHashCode(this.modificationDate); - result = 31 * result + ObjectUtils.nullSafeHashCode(this.readDate); - return result; + return ObjectUtils.nullSafeHash(this.type, this.name,this.filename, + this.charset, this.size, this.creationDate, this.modificationDate, this.readDate); } /** diff --git a/spring-web/src/main/java/org/springframework/http/HttpEntity.java b/spring-web/src/main/java/org/springframework/http/HttpEntity.java index 9b5be7c625..b3203e4e05 100644 --- a/spring-web/src/main/java/org/springframework/http/HttpEntity.java +++ b/spring-web/src/main/java/org/springframework/http/HttpEntity.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2021 the original author or authors. + * Copyright 2002-2023 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. @@ -141,7 +141,7 @@ public class HttpEntity { @Override public int hashCode() { - return (ObjectUtils.nullSafeHashCode(this.headers) * 29 + ObjectUtils.nullSafeHashCode(this.body)); + return ObjectUtils.nullSafeHash(this.headers, this.body); } @Override diff --git a/spring-web/src/main/java/org/springframework/http/HttpRange.java b/spring-web/src/main/java/org/springframework/http/HttpRange.java index 9c0ecc6864..bc1d966657 100644 --- a/spring-web/src/main/java/org/springframework/http/HttpRange.java +++ b/spring-web/src/main/java/org/springframework/http/HttpRange.java @@ -21,6 +21,7 @@ import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.List; +import java.util.Objects; import java.util.StringJoiner; import org.springframework.core.io.InputStreamResource; @@ -276,8 +277,7 @@ public abstract class HttpRange { @Override public int hashCode() { - return (ObjectUtils.nullSafeHashCode(this.firstPos) * 31 + - ObjectUtils.nullSafeHashCode(this.lastPos)); + return Objects.hash(this.firstPos, this.lastPos); } @Override diff --git a/spring-web/src/main/java/org/springframework/http/ProblemDetail.java b/spring-web/src/main/java/org/springframework/http/ProblemDetail.java index cbe60aa353..37f2b6ce80 100644 --- a/spring-web/src/main/java/org/springframework/http/ProblemDetail.java +++ b/spring-web/src/main/java/org/springframework/http/ProblemDetail.java @@ -19,6 +19,7 @@ package org.springframework.http; import java.net.URI; import java.util.LinkedHashMap; import java.util.Map; +import java.util.Objects; import org.springframework.lang.Nullable; import org.springframework.util.Assert; @@ -244,13 +245,8 @@ public class ProblemDetail { @Override public int hashCode() { - int result = this.type.hashCode(); - result = 31 * result + ObjectUtils.nullSafeHashCode(getTitle()); - result = 31 * result + this.status; - result = 31 * result + ObjectUtils.nullSafeHashCode(this.detail); - result = 31 * result + ObjectUtils.nullSafeHashCode(this.instance); - result = 31 * result + ObjectUtils.nullSafeHashCode(this.properties); - return result; + return Objects.hash(this.type, getTitle(), this.status, this.detail, + this.instance, this.properties); } @Override diff --git a/spring-web/src/main/java/org/springframework/web/util/HierarchicalUriComponents.java b/spring-web/src/main/java/org/springframework/web/util/HierarchicalUriComponents.java index 7314cf92eb..d3f0229b37 100644 --- a/spring-web/src/main/java/org/springframework/web/util/HierarchicalUriComponents.java +++ b/spring-web/src/main/java/org/springframework/web/util/HierarchicalUriComponents.java @@ -24,6 +24,7 @@ import java.nio.charset.Charset; import java.util.ArrayList; import java.util.Collections; import java.util.List; +import java.util.Objects; import java.util.StringJoiner; import java.util.function.BiFunction; import java.util.function.UnaryOperator; @@ -566,14 +567,8 @@ final class HierarchicalUriComponents extends UriComponents { @Override public int hashCode() { - int result = ObjectUtils.nullSafeHashCode(getScheme()); - result = 31 * result + ObjectUtils.nullSafeHashCode(this.userInfo); - result = 31 * result + ObjectUtils.nullSafeHashCode(this.host); - result = 31 * result + ObjectUtils.nullSafeHashCode(this.port); - result = 31 * result + this.path.hashCode(); - result = 31 * result + this.queryParams.hashCode(); - result = 31 * result + ObjectUtils.nullSafeHashCode(getFragment()); - return result; + return Objects.hash(getScheme(), this.userInfo, this.host, this.port, + this.path, this.queryParams, getFragment()); } diff --git a/spring-web/src/main/java/org/springframework/web/util/OpaqueUriComponents.java b/spring-web/src/main/java/org/springframework/web/util/OpaqueUriComponents.java index 3c886b4523..de437e6db0 100644 --- a/spring-web/src/main/java/org/springframework/web/util/OpaqueUriComponents.java +++ b/spring-web/src/main/java/org/springframework/web/util/OpaqueUriComponents.java @@ -21,6 +21,7 @@ import java.net.URISyntaxException; import java.nio.charset.Charset; import java.util.Collections; import java.util.List; +import java.util.Objects; import org.springframework.lang.Nullable; import org.springframework.util.LinkedMultiValueMap; @@ -166,10 +167,7 @@ final class OpaqueUriComponents extends UriComponents { @Override public int hashCode() { - int result = ObjectUtils.nullSafeHashCode(getScheme()); - result = 31 * result + ObjectUtils.nullSafeHashCode(this.ssp); - result = 31 * result + ObjectUtils.nullSafeHashCode(getFragment()); - return result; + return Objects.hash(getScheme(), this.ssp, getFragment()); } } diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/socket/CloseStatus.java b/spring-webflux/src/main/java/org/springframework/web/reactive/socket/CloseStatus.java index 4d3d5f8569..2ca52cacb3 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/socket/CloseStatus.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/socket/CloseStatus.java @@ -16,6 +16,8 @@ package org.springframework.web.reactive.socket; +import java.util.Objects; + import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.ObjectUtils; @@ -231,7 +233,7 @@ public final class CloseStatus { @Override public int hashCode() { - return this.code * 29 + ObjectUtils.nullSafeHashCode(this.reason); + return Objects.hash(this.code, this.reason); } @Override diff --git a/spring-websocket/src/main/java/org/springframework/web/socket/CloseStatus.java b/spring-websocket/src/main/java/org/springframework/web/socket/CloseStatus.java index 70192c72fb..1c95288c39 100644 --- a/spring-websocket/src/main/java/org/springframework/web/socket/CloseStatus.java +++ b/spring-websocket/src/main/java/org/springframework/web/socket/CloseStatus.java @@ -17,6 +17,7 @@ package org.springframework.web.socket; import java.io.Serializable; +import java.util.Objects; import org.springframework.lang.Nullable; import org.springframework.util.Assert; @@ -213,7 +214,7 @@ public final class CloseStatus implements Serializable { @Override public int hashCode() { - return this.code * 29 + ObjectUtils.nullSafeHashCode(this.reason); + return Objects.hash(this.code, this.reason); } @Override