→阿童沐

財富==支撐一個人生存多長時間的能力!

导航

HashSet集合类 与 hashCode()、equals()详解-


Object类的equals()方法特点:        四十五讲

 

1> 自反性: x.equals(x)应该返回true.

2> 对称性: x.equals(y)为true,那么y.equals(x)也为true;反之亦然.

3> 传递性: x.equals(y)为true,并且y.equals(z)为true,那么x.equals(z)也应该为true;反之亦然.

4> 一致性: x.equals(y)的第一次调用为true,那么x.equals(y)的第二次,第三次,第n次调用也应该为true,前提条件是在比较过程中没有修改xy;反之亦然.

5> 对于非空引用x, x.equals(null)返回false

 


Object类的hashCode()方法特点:               五十三-02:00

1> 在同一个Java应用程序同一次执行过程当中,对于同一个对象的hashCode方法的多次调用,他们应该返回同样的值(前提是该对象的信息没有发生变化).

2> 对于两个对象来说,如果使用equals方法比较返回true,那么这两个对象的hashCode()值一定是相同的.(强制要求)

3> 对于两个对象来说,如果使用equals方法比较返回false,那么这两个对象的hashCode()值可以不相同也可以相同,这里没有强制要求,但是如果实现两者hashCode()值不相同,则可以提高HashTable的性能.

4> 对于Object类来说,不同的Object对象的hashCode值是不同的(Object类的hashCode值表示的是对象的地址).

注意:可以这样子记忆,两个对象进行equals()比较为true,代表两个对象的状态完全一致,即对象中的私有域完全相同,而计算hashCode()时使用的是每个对象中部分或是全部的私有域进行计算得到的一个整数值,因此如果两个对象的状态(私有域)完全相同,则通过这两个对象的状态(对应的私有域)计算出来的hashCode()一定完全相同,但是反过来则不一定成立。


当使用HashSet(仅仅是HashSet适用,其他Set例如:SortedSet就不适用,Set的名称也可以看出来HashSet要使用到hashCode()方法)时,hashCode()方法就会得到调用.他用于判断已经存储在集合中的所有对象hashCode值是否与即将增加的对象的hashCode一致:

1> 如果不一致,则直接加入到集合当中;

2> 如果一致,则再进行equals()方法的比较:

  1) 如果equals()方法返回true,则表示对象已经加入进去了,就不会再增加当前对象;

  2) 如果equals()方法返回false,则表示对象还没有加入进去,当前对象将会被加入到HashSet当中.

 一般情况下,对于自定义类,都有可能放在set当中,正是因为这个原因,我们一定要对Object类中的equals()方法和hashCode()方法进行重写。

 之所以存在这样的比较机制是因为集合中元素是互异的,相同元素是无法同时加入到Set当中。

自定义类不需要使用Object类提供的equals()和hashCode()方法,转而使用自己编写的equals()方法和hashCode()方法,在实际开发过程中,判断一个对象能不能放在集合当中,大多数情况都是根据对象的内容来决定的,而不是根据地址来决定的.

下面是String类的hashCode()方法中的算法,也是根据字符串内容计算得来,而不是根据地址计算得来:

例:

package cn.edu.bupt.array;

import java.util.HashSet;

public class SetTest1
{
public static void main(String[] args)
{
HashSet<Person> set = new HashSet<Person>();

Person p1 = new Person("zhangsan");
Person p2 = new Person("zhangsan");
Person p3 = new Person("lisi");
System.out.println(set.add(p1));
System.out.println(set.add(p2));
System.out.println(set.add(p3));

System.out.println(set);
}
}

class Person
{
private String name = null;

public Person(String name)
{
super();
this.name = name;
}

@Override
public int hashCode()
{
return this.name.hashCode();
}

@Override
public boolean equals(Object obj)
{
if (this == obj)
{
return true;
}
if (null != obj && obj instanceof Person)
{
Person p = (Person)obj;
if (this.name.equals(p.name))
{
return true;
}
}
return false;
}
}


 

利用Eclipse可以自动生成自定义类的equals()方法和hashCode()方法。

选择自定义类,菜单栏 -> Source -> Generate hashCode() and equals()... 

点击OK即可生成相应的两个方法.


注意:对于hashCode()方法的使用一般来说只有在放入Set当中时才会被调用,平时使用的时候,是不会去调用hashCode的,但是你是不知道你的类是否可能被其他人放入集合当中的,因此一般需要重写这两个方法.

posted on 2012-03-20 15:46  阿童沐  阅读(306)  评论(0)    收藏  举报