Java: use deepEquals() / deepHashCode() for multi-dimensional arrays (IDEA-199543)

when generating equals() and hashCode() methods using the "java.util.Objects.equals() and hash() (java 7+)" template

GitOrigin-RevId: a863b875fa482542bbb9b2efc5e61cfa2bfb787d
This commit is contained in:
Bas Leijdekkers
2023-11-19 22:07:30 +01:00
committed by intellij-monorepo-bot
parent f8773787b2
commit caab7e4bf9
9 changed files with 79 additions and 104 deletions

View File

@@ -47,8 +47,7 @@ public final class EqualsHashCodeTemplatesManager extends TemplatesManager {
@NonNls public static final String EQUALS_HASH_CODE_BUILDER_APACHE_COMMONS_LANG = "Equals/HashCodeBuilder (Apache commons-lang)";
@NonNls public static final String EQUALS_HASH_CODE_BUILDER_APACHE_COMMONS_LANG_3 = "Equals/HashCodeBuilder (Apache commons-lang 3)";
@NonNls public static final String OBJECTS_EQUAL_AND_HASH_CODE_GUAVA = "Objects.equal() and hashCode() (Guava)";
@NonNls public static final String JAVA_UTIL_OBJECTS_EQUALS_AND_HASH_CODE = "java.util.Objects.equals() and hashCode() (java 7+)";
@NonNls public static final String JAVA_UTIL_OBJECTS_EQUALS_AND_HASH_CODE = "java.util.Objects.equals() and hash() (java 7+)";
public static EqualsHashCodeTemplatesManager getInstance() {
return ApplicationManager.getApplication().getService(EqualsHashCodeTemplatesManager.class);

View File

@@ -4,28 +4,28 @@ public boolean equals(##
final ##
#end
Object $paramName){
#addEqualsPrologue()
#addClassInstance()
return ##
#set($i = 0)
#foreach($field in $fields)
#if ($i > 0)
&& ##
#end
#set($i = $i + 1)
#if ($field.primitive)
#if ($field.double || $field.float)
#addDoubleFieldComparisonConditionDirect($field) ##
#else
#addPrimitiveFieldComparisonConditionDirect($field) ##
#end
#elseif ($field.enum)
#addPrimitiveFieldComparisonConditionDirect($field) ##
#elseif ($field.array)
java.util.Arrays.equals($field.accessor, ${classInstanceName}.$field.accessor)##
#else
java.util.Objects.equals($field.accessor, ${classInstanceName}.$field.accessor)##
#end
#end
;
#addEqualsPrologue()
#addClassInstance()
return ##
#set($i = 0)
#foreach($field in $fields)
#if ($i > 0)
&& ##
#end
#set($i = $i + 1)
#if ($field.primitive)
#if ($field.double || $field.float)
#addDoubleFieldComparisonConditionDirect($field) ##
#else
#addPrimitiveFieldComparisonConditionDirect($field) ##
#end
#elseif ($field.enum)
#addPrimitiveFieldComparisonConditionDirect($field) ##
#elseif ($field.array)
java.util.Objects.deepEquals($field.accessor, ${classInstanceName}.$field.accessor)##
#else
java.util.Objects.equals($field.accessor, ${classInstanceName}.$field.accessor)##
#end
#end
;
}

View File

@@ -1,79 +1,32 @@
public int hashCode() {
#if (!$superHasHashCode && $fields.size()==1)
#if ($fields[0].array)
return java.util.Arrays.hashCode($fields[0].accessor);
#if (!$fields[0].array)
return java.util.Objects.hashCode($fields[0].accessor);
#elseif ($field.nestedArray)
return java.util.Arrays.deepHashCode($fields[0].accessor);
#else
return java.util.Objects.hashCode($fields[0].accessor);
return java.util.Arrays.hashCode($fields[0].accessor);
#end
#else
#set($hasArrays = false)
#set($hasNoArrays = false)
return java.util.Objects.hash(##
#set($i = 0)
#if($superHasHashCode)
super.hashCode() ##
#set($i = 1)
#end
#foreach($field in $fields)
#if ($field.array)
#set($hasArrays = true)
#if ($i > 0)
, ##
#end
#if(!$field.array)
$field.accessor ##
#elseif ($field.nestedArray)
java.util.Arrays.deepHashCode($field.accessor)##
#else
#set($hasNoArrays = true)
java.util.Arrays.hashCode($field.accessor)##
#end
#set($i = $i + 1)
#end
#if (!$hasArrays)
return java.util.Objects.hash(##
#set($i = 0)
#if($superHasHashCode)
super.hashCode() ##
#set($i = 1)
#end
#foreach($field in $fields)
#if ($i > 0)
, ##
#end
$field.accessor ##
#set($i = $i + 1)
#end
);
#else
#set($resultName = $helper.getUniqueLocalVarName("result", $fields, $settings))
#set($resultAssigned = false)
#set($resultDeclarationCompleted = false)
int $resultName ##
#if($hasNoArrays)
= java.util.Objects.hash(##
#set($i = 0)
#if($superHasHashCode)
super.hashCode() ##
#set($i = 1)
#end
#foreach($field in $fields)
#if(!$field.array)
#if ($i > 0)
, ##
#end
$field.accessor ##
#set($i = $i + 1)
#end
#end
);
#set($resultAssigned = true)
#set($resultDeclarationCompleted = true)
#elseif($superHasHashCode)
= super.hashCode(); ##
#set($resultAssigned = true)
#set($resultDeclarationCompleted = true)
#end
#foreach($field in $fields)
#if($field.array)
#if ($resultDeclarationCompleted)
$resultName ##
#end
= ##
#if ($resultAssigned)
31 * $resultName + ##
#end
java.util.Arrays.hashCode($field.accessor);
#set($resultAssigned = true)
#set($resultDeclarationCompleted = true)
#end
#end
return $resultName;
#end
);
#end
}

View File

@@ -12,14 +12,11 @@ class A {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
final A a = (A) o;
return i == a.i && Objects.equals(s, a.s) && Arrays.equals(a1, a.a1) && Arrays.equals(a2, a.a2);
return i == a.i && Objects.equals(s, a.s) && Objects.deepEquals(a1, a.a1) && Objects.deepEquals(a2, a.a2);
}
@Override
public int hashCode() {
int result = Objects.hash(i, s);
result = 31 * result + Arrays.hashCode(a1);
result = 31 * result + Arrays.hashCode(a2);
return result;
return Objects.hash(i, s, Arrays.hashCode(a1), Arrays.hashCode(a2));
}
}

View File

@@ -1,4 +1,5 @@
import java.util.Arrays;
import java.util.Objects;
class I {
public int hashCode() {
@@ -18,13 +19,11 @@ class A extends I {
if (o == null || getClass() != o.getClass()) return false;
if (!super.equals(o)) return false;
final A a = (A) o;
return Arrays.equals(a1, a.a1);
return Objects.deepEquals(a1, a.a1);
}
@Override
public int hashCode() {
int result = super.hashCode();
result = 31 * result + Arrays.hashCode(a1);
return result;
return Objects.hash(super.hashCode(), Arrays.hashCode(a1));
}
}

View File

@@ -0,0 +1,19 @@
import java.util.Arrays;
import java.util.Objects;
class X {
private String[][] s = null;
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
final X x = (X) o;
return Objects.deepEquals(s, x.s);
}
@Override
public int hashCode() {
return Arrays.deepHashCode(s);
}
}

View File

@@ -1,4 +1,5 @@
import java.util.Arrays;
import java.util.Objects;
class A {
int[] a1;
@@ -8,7 +9,7 @@ class A {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
final A a = (A) o;
return Arrays.equals(a1, a.a1);
return Objects.deepEquals(a1, a.a1);
}
@Override

View File

@@ -0,0 +1,3 @@
class X {
private String[][] s = null;
}

View File

@@ -138,6 +138,10 @@ public class GenerateEqualsTest extends LightJavaCodeInsightTestCase {
doTestWithTemplate(EqualsHashCodeTemplatesManager.JAVA_UTIL_OBJECTS_EQUALS_AND_HASH_CODE);
}
public void testSingleArrayFieldWithObjectsTemplate() {
doTestWithTemplate(EqualsHashCodeTemplatesManager.JAVA_UTIL_OBJECTS_EQUALS_AND_HASH_CODE);
}
public void testArrayAndNotOnlyArrayWithObjectsTemplate() {
doTestWithTemplate(EqualsHashCodeTemplatesManager.JAVA_UTIL_OBJECTS_EQUALS_AND_HASH_CODE);
}