在Java中重写equals和hashCode时应该考虑哪些问题?

发布于 2024-07-04 13:20:13 字数 41 浏览 7 评论 0原文

重写 equals 和 hashCode 时必须考虑哪些问题/陷阱?

What issues / pitfalls must be considered when overriding equals and hashCode?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(11

芯好空 2024-07-11 13:20:14

我发现的一个问题是两个对象包含彼此的引用(一个例子是父/子关系,在父对象上使用一种方便的方法来获取所有子对象)。
例如,在进行 Hibernate 映射时,此类事情相当常见。

如果您在 hashCode 或 equals 测试中包含关系的两端,则可能会进入以 StackOverflowException 结束的递归循环。
最简单的解决方案是不在方法中包含 getChildren 集合。

One gotcha I have found is where two objects contain references to each other (one example being a parent/child relationship with a convenience method on the parent to get all children).
These sorts of things are fairly common when doing Hibernate mappings for example.

If you include both ends of the relationship in your hashCode or equals tests it's possible to get into a recursive loop which ends in a StackOverflowException.
The simplest solution is to not include the getChildren collection in the methods.

全部不再 2024-07-11 13:20:14

逻辑上我们有:

a.getClass().equals(b.getClass()) && a.equals(b) ⇒ a.hashCode() == b.hashCode()

反之亦然!

Logically we have:

a.getClass().equals(b.getClass()) && a.equals(b)a.hashCode() == b.hashCode()

But not vice-versa!

ζ澈沫 2024-07-11 13:20:14

仍然令人惊讶的是没有人为此推荐番石榴库。

 //Sample taken from a current working project of mine just to illustrate the idea

    @Override
    public int hashCode(){
        return Objects.hashCode(this.getDate(), this.datePattern);
    }

    @Override
    public boolean equals(Object obj){
        if ( ! obj instanceof DateAndPattern ) {
            return false;
        }
        return Objects.equal(((DateAndPattern)obj).getDate(), this.getDate())
                && Objects.equal(((DateAndPattern)obj).getDate(), this.getDatePattern());
    }

Still amazed that none recommended the guava library for this.

 //Sample taken from a current working project of mine just to illustrate the idea

    @Override
    public int hashCode(){
        return Objects.hashCode(this.getDate(), this.datePattern);
    }

    @Override
    public boolean equals(Object obj){
        if ( ! obj instanceof DateAndPattern ) {
            return false;
        }
        return Objects.equal(((DateAndPattern)obj).getDate(), this.getDate())
                && Objects.equal(((DateAndPattern)obj).getDate(), this.getDatePattern());
    }
黑白记忆 2024-07-11 13:20:14

超类 java.lang.Object 中有两个方法。 我们需要将它们重写为自定义对象。

public boolean equals(Object obj)
public int hashCode()

只要它们相等,相等的对象就必须产生相同的哈希码,但是不相等的对象不需要产生不同的哈希码。

public class Test
{
    private int num;
    private String data;
    public boolean equals(Object obj)
    {
        if(this == obj)
            return true;
        if((obj == null) || (obj.getClass() != this.getClass()))
            return false;
        // object must be Test at this point
        Test test = (Test)obj;
        return num == test.num &&
        (data == test.data || (data != null && data.equals(test.data)));
    }

    public int hashCode()
    {
        int hash = 7;
        hash = 31 * hash + num;
        hash = 31 * hash + (null == data ? 0 : data.hashCode());
        return hash;
    }

    // other methods
}

如果您想了解更多信息,请检查此链接 http://www.javaranch。 com/journal/2002/10/equalhash.html

这是另一个例子,
http://java67.blogspot .com/2013/04/example-of-overriding-equals-hashcode-compareTo-java-method.html

玩得开心! @.@

There are two methods in super class as java.lang.Object. We need to override them to custom object.

public boolean equals(Object obj)
public int hashCode()

Equal objects must produce the same hash code as long as they are equal, however unequal objects need not produce distinct hash codes.

public class Test
{
    private int num;
    private String data;
    public boolean equals(Object obj)
    {
        if(this == obj)
            return true;
        if((obj == null) || (obj.getClass() != this.getClass()))
            return false;
        // object must be Test at this point
        Test test = (Test)obj;
        return num == test.num &&
        (data == test.data || (data != null && data.equals(test.data)));
    }

    public int hashCode()
    {
        int hash = 7;
        hash = 31 * hash + num;
        hash = 31 * hash + (null == data ? 0 : data.hashCode());
        return hash;
    }

    // other methods
}

If you want get more, please check this link as http://www.javaranch.com/journal/2002/10/equalhash.html

This is another example,
http://java67.blogspot.com/2013/04/example-of-overriding-equals-hashcode-compareTo-java-method.html

Have Fun! @.@

山田美奈子 2024-07-11 13:20:14

在检查成员相等性之前,有几种方法可以检查类相等性,我认为这两种方法在适当的情况下都很有用。

  1. 使用 instanceof 运算符。
  2. 使用 this.getClass().equals(that.getClass()) 。

我在 final equals 实现中使用#1,或者在实现规定 equals 算法的接口时使用#1(例如 java.util 集合接口 - 检查的正确方法)与 (obj instanceof Set) 或您正在实现的任何接口)。 当 equals 可以被覆盖时,这通常是一个糟糕的选择,因为这会破坏对称性。

选项 #2 允许安全地扩展类,而不会覆盖 equals 或破坏对称性。

如果您的类也是Comparable,则equalscompareTo 方法也应该一致。 以下是 Comparable 类中 equals 方法的模板:

final class MyClass implements Comparable<MyClass>
{

  …

  @Override
  public boolean equals(Object obj)
  {
    /* If compareTo and equals aren't final, we should check with getClass instead. */
    if (!(obj instanceof MyClass)) 
      return false;
    return compareTo((MyClass) obj) == 0;
  }

}

There are a couple of ways to do your check for class equality before checking member equality, and I think both are useful in the right circumstances.

  1. Use the instanceof operator.
  2. Use this.getClass().equals(that.getClass()).

I use #1 in a final equals implementation, or when implementing an interface that prescribes an algorithm for equals (like the java.util collection interfaces—the right way to check with with (obj instanceof Set) or whatever interface you're implementing). It's generally a bad choice when equals can be overridden because that breaks the symmetry property.

Option #2 allows the class to be safely extended without overriding equals or breaking symmetry.

If your class is also Comparable, the equals and compareTo methods should be consistent too. Here's a template for the equals method in a Comparable class:

final class MyClass implements Comparable<MyClass>
{

  …

  @Override
  public boolean equals(Object obj)
  {
    /* If compareTo and equals aren't final, we should check with getClass instead. */
    if (!(obj instanceof MyClass)) 
      return false;
    return compareTo((MyClass) obj) == 0;
  }

}
烟─花易冷 2024-07-11 13:20:14

对于平等,请查看平等的秘密作者:安吉莉卡·兰格。 我非常爱它。 她还是一个关于Java 泛型的精彩常见问题解答。 此处查看她的其他文章(向下滚动到“Core Java”),她在其中还继续第 2 部分和“混合类型比较”。 祝您阅读愉快!

For equals, look into Secrets of Equals by Angelika Langer. I love it very much. She's also a great FAQ about Generics in Java. View her other articles here (scroll down to "Core Java"), where she also goes on with Part-2 and "mixed type comparison". Have fun reading them!

妄司 2024-07-11 13:20:14

equals()方法用于判断两个对象是否相等。

因为 int 值 10 始终等于 10。但是这个 equals() 方法是关于两个对象相等的。 当我们说对象时,它就会有属性。 为了决定平等,需要考虑这些属性。 不必考虑所有属性来确定相等性,并且可以根据类定义和上下文来决定。 然后可以重写 equals() 方法。

每当我们重写 equals() 方法时,我们都应该重写 hashCode() 方法。 如果没有,会发生什么? 如果我们在应用程序中使用哈希表,它将不会按预期运行。 由于 hashCode 用于确定存储的值的相等性,因此它不会返回键的正确对应值。

给出的默认实现是 Object 类中的 hashCode() 方法,使用对象的内部地址并将其转换为整数并返回。

public class Tiger {
  private String color;
  private String stripePattern;
  private int height;

  @Override
  public boolean equals(Object object) {
    boolean result = false;
    if (object == null || object.getClass() != getClass()) {
      result = false;
    } else {
      Tiger tiger = (Tiger) object;
      if (this.color == tiger.getColor()
          && this.stripePattern == tiger.getStripePattern()) {
        result = true;
      }
    }
    return result;
  }

  // just omitted null checks
  @Override
  public int hashCode() {
    int hash = 3;
    hash = 7 * hash + this.color.hashCode();
    hash = 7 * hash + this.stripePattern.hashCode();
    return hash;
  }

  public static void main(String args[]) {
    Tiger bengalTiger1 = new Tiger("Yellow", "Dense", 3);
    Tiger bengalTiger2 = new Tiger("Yellow", "Dense", 2);
    Tiger siberianTiger = new Tiger("White", "Sparse", 4);
    System.out.println("bengalTiger1 and bengalTiger2: "
        + bengalTiger1.equals(bengalTiger2));
    System.out.println("bengalTiger1 and siberianTiger: "
        + bengalTiger1.equals(siberianTiger));

    System.out.println("bengalTiger1 hashCode: " + bengalTiger1.hashCode());
    System.out.println("bengalTiger2 hashCode: " + bengalTiger2.hashCode());
    System.out.println("siberianTiger hashCode: "
        + siberianTiger.hashCode());
  }

  public String getColor() {
    return color;
  }

  public String getStripePattern() {
    return stripePattern;
  }

  public Tiger(String color, String stripePattern, int height) {
    this.color = color;
    this.stripePattern = stripePattern;
    this.height = height;

  }
}

示例代码输出:

bengalTiger1 and bengalTiger2: true 
bengalTiger1 and siberianTiger: false 
bengalTiger1 hashCode: 1398212510 
bengalTiger2 hashCode: 1398212510 
siberianTiger hashCode: –1227465966

equals() method is used to determine the equality of two objects.

as int value of 10 is always equal to 10. But this equals() method is about equality of two objects. When we say object, it will have properties. To decide about equality those properties are considered. It is not necessary that all properties must be taken into account to determine the equality and with respect to the class definition and context it can be decided. Then the equals() method can be overridden.

we should always override hashCode() method whenever we override equals() method. If not, what will happen? If we use hashtables in our application, it will not behave as expected. As the hashCode is used in determining the equality of values stored, it will not return the right corresponding value for a key.

Default implementation given is hashCode() method in Object class uses the internal address of the object and converts it into integer and returns it.

public class Tiger {
  private String color;
  private String stripePattern;
  private int height;

  @Override
  public boolean equals(Object object) {
    boolean result = false;
    if (object == null || object.getClass() != getClass()) {
      result = false;
    } else {
      Tiger tiger = (Tiger) object;
      if (this.color == tiger.getColor()
          && this.stripePattern == tiger.getStripePattern()) {
        result = true;
      }
    }
    return result;
  }

  // just omitted null checks
  @Override
  public int hashCode() {
    int hash = 3;
    hash = 7 * hash + this.color.hashCode();
    hash = 7 * hash + this.stripePattern.hashCode();
    return hash;
  }

  public static void main(String args[]) {
    Tiger bengalTiger1 = new Tiger("Yellow", "Dense", 3);
    Tiger bengalTiger2 = new Tiger("Yellow", "Dense", 2);
    Tiger siberianTiger = new Tiger("White", "Sparse", 4);
    System.out.println("bengalTiger1 and bengalTiger2: "
        + bengalTiger1.equals(bengalTiger2));
    System.out.println("bengalTiger1 and siberianTiger: "
        + bengalTiger1.equals(siberianTiger));

    System.out.println("bengalTiger1 hashCode: " + bengalTiger1.hashCode());
    System.out.println("bengalTiger2 hashCode: " + bengalTiger2.hashCode());
    System.out.println("siberianTiger hashCode: "
        + siberianTiger.hashCode());
  }

  public String getColor() {
    return color;
  }

  public String getStripePattern() {
    return stripePattern;
  }

  public Tiger(String color, String stripePattern, int height) {
    this.color = color;
    this.stripePattern = stripePattern;
    this.height = height;

  }
}

Example Code Output:

bengalTiger1 and bengalTiger2: true 
bengalTiger1 and siberianTiger: false 
bengalTiger1 hashCode: 1398212510 
bengalTiger2 hashCode: 1398212510 
siberianTiger hashCode: –1227465966
时光无声 2024-07-11 13:20:14

关于 obj.getClass() != getClass() 的说明。

该语句是 equals() 继承不友好的结果。 JLS(Java 语言规范)规定,如果 A.equals(B) == trueB.equals(A) 也必须返回 true。 如果您忽略该语句,则继承重写 equals() 的类(并更改其行为)将违反此规范。

考虑以下示例,说明省略该语句时会发生什么:

    class A {
      int field1;

      A(int field1) {
        this.field1 = field1;
      }

      public boolean equals(Object other) {
        return (other != null && other instanceof A && ((A) other).field1 == field1);
      }
    }

    class B extends A {
        int field2;

        B(int field1, int field2) {
            super(field1);
            this.field2 = field2;
        }

        public boolean equals(Object other) {
            return (other != null && other instanceof B && ((B)other).field2 == field2 && super.equals(other));
        }
    }    

执行 new A(1).equals(new A(1)) 另外,new B(1,1).equals( new B(1,1)) 结果给出 true,正如它应该的那样。

这看起来非常好,但是看看如果我们尝试使用这两个类会发生什么:

A a = new A(1);
B b = new B(1,1);
a.equals(b) == true;
b.equals(a) == false;

显然,这是错误的。

如果要保证对称条件。 a=b 如果 b=a 并且里氏替换原则不仅在 B 实例的情况下调用 super.equals(other),而且在之后检查 A 实例:

if (other instanceof B )
   return (other != null && ((B)other).field2 == field2 && super.equals(other)); 
if (other instanceof A) return super.equals(other); 
   else return false;

将输出:

a.equals(b) == true;
b.equals(a) == true;

其中,如果 a 不是 B 的引用,那么它可能是类 A< 的引用/code> (因为您扩展了它),在这种情况下您调用 super.equals() too

A clarification about the obj.getClass() != getClass().

This statement is the result of equals() being inheritance unfriendly. The JLS (Java language specification) specifies that if A.equals(B) == true then B.equals(A) must also return true. If you omit that statement inheriting classes that override equals() (and change its behavior) will break this specification.

Consider the following example of what happens when the statement is omitted:

    class A {
      int field1;

      A(int field1) {
        this.field1 = field1;
      }

      public boolean equals(Object other) {
        return (other != null && other instanceof A && ((A) other).field1 == field1);
      }
    }

    class B extends A {
        int field2;

        B(int field1, int field2) {
            super(field1);
            this.field2 = field2;
        }

        public boolean equals(Object other) {
            return (other != null && other instanceof B && ((B)other).field2 == field2 && super.equals(other));
        }
    }    

Doing new A(1).equals(new A(1)) Also, new B(1,1).equals(new B(1,1)) result give out true, as it should.

This looks all very good, but look what happens if we try to use both classes:

A a = new A(1);
B b = new B(1,1);
a.equals(b) == true;
b.equals(a) == false;

Obviously, this is wrong.

If you want to ensure the symmetric condition. a=b if b=a and the Liskov substitution principle call super.equals(other) not only in the case of B instance, but check after for A instance:

if (other instanceof B )
   return (other != null && ((B)other).field2 == field2 && super.equals(other)); 
if (other instanceof A) return super.equals(other); 
   else return false;

Which will output:

a.equals(b) == true;
b.equals(a) == true;

Where, if a is not a reference of B, then it might be a be a reference of class A (because you extend it), in this case you call super.equals() too.

猫烠⑼条掵仅有一顆心 2024-07-11 13:20:14

如果您正在处理使用像 Hibernate 这样的对象关系映射器 (ORM) 持久化的类,并且您不认为这已经变得不合理的复杂,那么有一些问题值得注意!

延迟加载的对象是子类

如果您的对象使用 ORM 进行持久化,则在许多情况下您将处理动态代理以避免过早从数据存储中加载对象。 这些代理作为您自己的类的子类来实现。 这意味着 this.getClass() == o.getClass() 将返回 false。 例如:

Person saved = new Person("John Doe");
Long key = dao.save(saved);
dao.flush();
Person retrieved = dao.retrieve(key);
saved.getClass().equals(retrieved.getClass()); // Will return false if Person is loaded lazy

如果您正在处理 ORM,则使用 o instanceof Person 是唯一能够正确运行的方法。

延迟加载的对象具有空字段< ORM

通常使用 getter 来强制加载延迟加载的对象。 这意味着如果 person 延迟加载,person.name 将为 null,即使 person.getName()强制加载并返回“John Doe”。 根据我的经验,这种情况在 hashCode()equals() 中更常见。

如果您正在处理 ORM,请确保始终使用 getter,并且切勿在 hashCode()equals() 中使用字段引用。

保存对象将改变其状态

持久对象通常使用id字段来保存对象的键。 首次保存对象时,此字段将自动更新。 不要在 hashCode() 中使用 id 字段。 但您可以在 equals() 中使用它。

我经常使用的模式是

if (this.getId() == null) {
    return this == other;
}
else {
    return this.getId().equals(other.getId());
}

但是:您不能在 hashCode() 中包含 getId()。 如果这样做,当对象被持久化时,它的 hashCode 会发生变化。 如果该对象位于 HashSet 中,您将“永远”不会再找到它。

在我的 Person 示例中,我可能会使用 getName() 来表示 hashCodegetId() 以及 getName()(只是出于偏执)用于 equals()。 如果 hashCode() 存在一些“冲突”风险,那是可以的,但对于 equals() 则绝对不行。

hashCode() 应使用 equals() 中不变的属性子集

There are some issues worth noticing if you're dealing with classes that are persisted using an Object-Relationship Mapper (ORM) like Hibernate, if you didn't think this was unreasonably complicated already!

Lazy loaded objects are subclasses

If your objects are persisted using an ORM, in many cases you will be dealing with dynamic proxies to avoid loading object too early from the data store. These proxies are implemented as subclasses of your own class. This means thatthis.getClass() == o.getClass() will return false. For example:

Person saved = new Person("John Doe");
Long key = dao.save(saved);
dao.flush();
Person retrieved = dao.retrieve(key);
saved.getClass().equals(retrieved.getClass()); // Will return false if Person is loaded lazy

If you're dealing with an ORM, using o instanceof Person is the only thing that will behave correctly.

Lazy loaded objects have null-fields

ORMs usually use the getters to force loading of lazy loaded objects. This means that person.name will be null if person is lazy loaded, even if person.getName() forces loading and returns "John Doe". In my experience, this crops up more often in hashCode() and equals().

If you're dealing with an ORM, make sure to always use getters, and never field references in hashCode() and equals().

Saving an object will change its state

Persistent objects often use a id field to hold the key of the object. This field will be automatically updated when an object is first saved. Don't use an id field in hashCode(). But you can use it in equals().

A pattern I often use is

if (this.getId() == null) {
    return this == other;
}
else {
    return this.getId().equals(other.getId());
}

But: you cannot include getId() in hashCode(). If you do, when an object is persisted, its hashCode changes. If the object is in a HashSet, you'll "never" find it again.

In my Person example, I probably would use getName() for hashCode and getId() plus getName() (just for paranoia) for equals(). It's okay if there are some risk of "collisions" for hashCode(), but never okay for equals().

hashCode() should use the non-changing subset of properties from equals()

温柔一刀 2024-07-11 13:20:14

对于继承友好的实现,请查看 Tal Cohen 的解决方案,如何正确实现 equals() 方法?

摘要:

在他的书中 有效的 Java 编程语言指南(Addison-Wesley,2001 年),Joshua Bloch 声称“根本没有办法在保留 equals 契约的同时扩展可实例化类并添加方面。” 塔尔不同意。

他的解决方案是通过双向调用另一个非对称的blindlyEquals()来实现equals()。 blindlyEquals() 被子类重写,equals() 被继承,并且永远不会被重写。

示例:

class Point {
    private int x;
    private int y;
    protected boolean blindlyEquals(Object o) {
        if (!(o instanceof Point))
            return false;
        Point p = (Point)o;
        return (p.x == this.x && p.y == this.y);
    }
    public boolean equals(Object o) {
        return (this.blindlyEquals(o) && o.blindlyEquals(this));
    }
}

class ColorPoint extends Point {
    private Color c;
    protected boolean blindlyEquals(Object o) {
        if (!(o instanceof ColorPoint))
            return false;
        ColorPoint cp = (ColorPoint)o;
        return (super.blindlyEquals(cp) && 
        cp.color == this.color);
    }
}

请注意,如果要满足 里氏替换原则,则 equals() 必须跨继承层次结构工作。

For an inheritance-friendly implementation, check out Tal Cohen's solution, How Do I Correctly Implement the equals() Method?

Summary:

In his book Effective Java Programming Language Guide (Addison-Wesley, 2001), Joshua Bloch claims that "There is simply no way to extend an instantiable class and add an aspect while preserving the equals contract." Tal disagrees.

His solution is to implement equals() by calling another nonsymmetric blindlyEquals() both ways. blindlyEquals() is overridden by subclasses, equals() is inherited, and never overridden.

Example:

class Point {
    private int x;
    private int y;
    protected boolean blindlyEquals(Object o) {
        if (!(o instanceof Point))
            return false;
        Point p = (Point)o;
        return (p.x == this.x && p.y == this.y);
    }
    public boolean equals(Object o) {
        return (this.blindlyEquals(o) && o.blindlyEquals(this));
    }
}

class ColorPoint extends Point {
    private Color c;
    protected boolean blindlyEquals(Object o) {
        if (!(o instanceof ColorPoint))
            return false;
        ColorPoint cp = (ColorPoint)o;
        return (super.blindlyEquals(cp) && 
        cp.color == this.color);
    }
}

Note that equals() must work across inheritance hierarchies if the Liskov Substitution Principle is to be satisfied.

翻身的咸鱼 2024-07-11 13:20:14

理论(对于语言律师和数学爱好者):

equals() (javadoc) 必须定义一个等价关系(它必须是自反对称 和传递)。 此外,它必须一致(如果对象没有被修改,那么它必须保持返回相同的值)。 此外,o.equals(null) 必须始终返回 false。

hashCode() (javadoc) 也必须一致(如果对象没有根据 equals() 进行修改,则它必须保持返回相同的值)。

两种方法之间的关系是:

每当 a.equals(b) 时,a.hashCode() 必须与 b.hashCode() 相同.

实际上:

如果您覆盖其中一个,那么您应该覆盖另一个。

使用与计算 equals() 相同的字段集来计算 hashCode()

使用优秀的帮助器类 EqualsBuilder< /a> 和 HashCodeBuilder 来自 Apache Commons Lang 库。 一个例子:

public class Person {
    private String name;
    private int age;
    // ...

    @Override
    public int hashCode() {
        return new HashCodeBuilder(17, 31). // two randomly chosen prime numbers
            // if deriving: appendSuper(super.hashCode()).
            append(name).
            append(age).
            toHashCode();
    }

    @Override
    public boolean equals(Object obj) {
       if (!(obj instanceof Person))
            return false;
        if (obj == this)
            return true;

        Person rhs = (Person) obj;
        return new EqualsBuilder().
            // if deriving: appendSuper(super.equals(obj)).
            append(name, rhs.name).
            append(age, rhs.age).
            isEquals();
    }
}

还请记住:

当使用基于哈希的 集合地图 例如HashSetLinkedHashSet, HashMap, 哈希表,或 WeakHashMap,确保放入集合的关键对象的 hashCode() 在对象在集合中。 确保这一点的万无一失的方法是使您的密钥不可变,这还有其他好处< /a>.

The theory (for the language lawyers and the mathematically inclined):

equals() (javadoc) must define an equivalence relation (it must be reflexive, symmetric, and transitive). In addition, it must be consistent (if the objects are not modified, then it must keep returning the same value). Furthermore, o.equals(null) must always return false.

hashCode() (javadoc) must also be consistent (if the object is not modified in terms of equals(), it must keep returning the same value).

The relation between the two methods is:

Whenever a.equals(b), then a.hashCode() must be same as b.hashCode().

In practice:

If you override one, then you should override the other.

Use the same set of fields that you use to compute equals() to compute hashCode().

Use the excellent helper classes EqualsBuilder and HashCodeBuilder from the Apache Commons Lang library. An example:

public class Person {
    private String name;
    private int age;
    // ...

    @Override
    public int hashCode() {
        return new HashCodeBuilder(17, 31). // two randomly chosen prime numbers
            // if deriving: appendSuper(super.hashCode()).
            append(name).
            append(age).
            toHashCode();
    }

    @Override
    public boolean equals(Object obj) {
       if (!(obj instanceof Person))
            return false;
        if (obj == this)
            return true;

        Person rhs = (Person) obj;
        return new EqualsBuilder().
            // if deriving: appendSuper(super.equals(obj)).
            append(name, rhs.name).
            append(age, rhs.age).
            isEquals();
    }
}

Also remember:

When using a hash-based Collection or Map such as HashSet, LinkedHashSet, HashMap, Hashtable, or WeakHashMap, make sure that the hashCode() of the key objects that you put into the collection never changes while the object is in the collection. The bulletproof way to ensure this is to make your keys immutable, which has also other benefits.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文