1),判断两个对象的hashCode是否相等
如果不相等,认为两个对象也不相等,完毕
如果相等,转入2)
2),判断两个对象用equals运算是否相等,相等就返回true
class Weibo
{
private String name;
publicWeibo (String name)
{
this.name = name;
}
// 根据name判断两个 weibo 是否相等
public boolean equals(Object o)
{
if (this == o)
{
return true;
}
if (o.getClass() == Name.class)
{
Weibo weibo = (Weibo)o;
return weibo.name.equals(name);
}
return false;
}
// 根据 first 计算 Name 对象的 hashCode() 返回值
public int hashCode()
{
return name.hashCode();
}
public class HashSetTest
{
public static void main(String[] args)
{
HashSet<Weibo> set = new HashSet<Weibo>();
set.add(new Weibo("abc" );
set.add(new Weibo("abc" );
System.out.println(set);
}
}
执行结果:无法插入第二个对象。原因是什么,因为要判断hashcode,然后equals.
Weibo.hashcode中返回的是name,也就是说当name相同时,两个weibo的hashcode就相同,这样的话就开始判断equals 一判断是相同的。hashset
是不允许插入重复的。所以。
这就是hashset判断对象是否相同的原理。
结论Hashtable、HashMap、HashSet、LinkedHashMap中的key,需要判断该key对象的hashcode与equals。需要重写这两个方法。
hashcode用处,我们知道list与set区别,list中元素是有序的,元素可以重复;set元素无序,但元素不可重复。 如果保证既有序又不可重复呢?要想保证元素不重复,可两个元素是否重复应该依据什么来判断呢? 这就是Object.equals方法了。但是,如果每增加一个元素就检查一次,那么当元素很多时,后添加到集合中的元素比较的次数就非常多了。
Java采用了哈希表的原理, 哈希算法也称为散列算法,是将数据依特定算法直接指定到一个地址上. 初学者可以这样理解,hashCode方法实际上返回的就是对象存储的物理地址(实际可能并不是)。
有了hashCode,当集合要添加新的元素时,先调用这个元素的hashCode方法,就一下子能定位到它应该放置的物理位置上。
如果这个位置上没有元素,它就可以直接存储在这个位置上,不用再进行任何比较了;如果这个位置上已经有元素了,
就调用它的equals方法与新元素进行比较,相同的话就不存了,不相同就散列其它的地址。
所以这里存在一个冲突解决的问题。这样一来实际调用equals方法的次数就大大降低了,几乎只需要一两次.