Contents
  1. 1. [1]. 问题:内容相同但是地址不同的自定义对象如何避免重复的内容添加到HashSet中?
  2. 2. 【解决办法】必须重写hashCode和equals这两个方法
  3. 3. hashCode()的最重要的是:
  4. 4. 一。 在重写equals方法时,要注意满足离散数学上的特性
  5. 5. 二。 在重写equals方法时,还要顺手把 hashCode方法一起重写了。
  6. 6. 三。重写equals方法的一般步骤:

参考: http://blog.csdn.net/benjaminzhang666/article/details/9468605

[1]. 问题:内容相同但是地址不同的自定义对象如何避免重复的内容添加到HashSet中?

【解决办法】必须重写hashCode和equals这两个方法

hashCode()的最重要的是:

无论何时,对同一个对象调用hashCode()都应该生成同于的hash值

hashCode()必须基于对象的内容生成散列码,散列码不必是独一无二的,但是通过hashCode()和equals()必须能够完全确定对象的身份。

重写equals方法的注意事项

一。 在重写equals方法时,要注意满足离散数学上的特性

  • 自反性:对任意引用值X,x.equals(x)的返回值一定为true.

  • 对称性:对于任何引用值x,y,当且仅当y.equals(x)返回值为true时,x.equals(y)的返回值一定为true;

  • 传递性:如果x.equals(y)=true, y.equals(z)=true,则x.equals(z)=true

  • 一致性:如果参与比较的对象没任何改变,则对象比较的结果也不应该有任何改变

  • 非空性:任何非空的引用值X,x.equals(null)的返回值一定为false

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
@Override

public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (this.getClass() != obj.getClass()) {
return false;
}
//别用下面这个,有隐患
/*if(!(obj instanceof People))
return false;
*/


People p = (People)obj;
return this.name.equals(p.name)
&& this.age == p.age;
}

二。 在重写equals方法时,还要顺手把 hashCode方法一起重写了。

  这一点主要是考虑和集合类协同工作的需要。一般集合为加快存取速度,通常使用类hashtable的方式存取对象,

  hashCode() && equals() 则是判断待查找元素与集合中某个元素相等的依据。 而java中默认的hashCode是由对象的内存地址生成的, 如果重写了equals 而没重写 hashCode, 则会造成“A和B相等,A加入集合后,用B查询集合却查不到”的悖论。

三。重写equals方法的一般步骤:

  1. 使用==操作符检查“实参是否为指向对象的一个引用”。
  2. 使用getClass来检查实参是否为正确的类型,不要使用instanceof操作符检查“”。
  3. 把实参转换到正确的类型。
  4. 对于该类中每一个“关键”域,检查实参中的域与当前对象中对应的域值是否匹 配。

  5. 当你编写完成了equals方法之后,应该问自己三个问题:它是否是对称的、传
    递的、一致的?(其他两个特性通常会自行满足)如果答案是否定的,那么请找到
    这些特性未能满足的原因,再修改equals方法的代码。

Contents
  1. 1. [1]. 问题:内容相同但是地址不同的自定义对象如何避免重复的内容添加到HashSet中?
  2. 2. 【解决办法】必须重写hashCode和equals这两个方法
  3. 3. hashCode()的最重要的是:
  4. 4. 一。 在重写equals方法时,要注意满足离散数学上的特性
  5. 5. 二。 在重写equals方法时,还要顺手把 hashCode方法一起重写了。
  6. 6. 三。重写equals方法的一般步骤: