读书人

【转】hashCode()的功用

发布时间: 2012-12-18 12:43:41 作者: rapoo

【转】hashCode()的作用

http://blog.csdn.net/badboy_blue/archive/2009/01/06/3720509.aspx

public class Test { public static void main(String[] args) { HashSet set = new HashSet(); for (int i = 0; i <= 3; i++){ set.add(new Demo1(i,i)); }System.out.println(set);set.add(new Demo1(1,1)); System.out.println(set);System.out.println(set.contains(new Demo1(0,0))); System.out.println(set.add(new Demo1(1,1))); System.out.println(set.add(new Demo1(4,4))); System.out.println(set);}private static class Demo1 { private int value; private int id; public Demo1(int value,int id) { this.value = value; this.id=id; }public String toString() { return " value = " + value; }public boolean equals(Object o) { Demo1 a = (Demo1) o;return (a.value == value) ? true : false; }public int hashCode() { return id; }}}你分别注释掉hashCode()和 equals()来比较一下他们作用就可以拉,关键要自己动手看看比较的结果你就可以记得很清楚啦如果还不是很明确可以再看另一个例子:public final class Test { public static void main(String[] args) { Map m = new HashMap(); m.put(new PhoneNumber(020, 12345678), "shellfeng"); System.out.println(m.get(new PhoneNumber(020, 12345678))); }private static class PhoneNumber { /*** 区号*/private short areaCode; /*** 扩展号*/private short extension; public PhoneNumber(int areaCode, int extension) { this.areaCode = (short) areaCode; this.extension = (short) extension; }public boolean equals(Object o) { if (o == this) { return true; }if (!(o instanceof PhoneNumber)) { return false; }PhoneNumber pn = (PhoneNumber) o;return pn.extension == extension && pn.areaCode == areaCode; }/*** @see java.lang.Object#hashCode()* @return result就是我们得到的散列值,其实我们的计算过程可以多种,这里只不过是一个例子,需要你的灵活运用,使其接近你需要的理想结果*/public int hashCode() { int result = 17; result = 37 * result + areaCode; result = 37 * result + extension; return result; }}}

?
还是那句话:你注释掉hashCode()比较一下他们作用就可以拉,关键要自己动手看看比较的结果你就可以记得很清楚啦

总结
hashCode() 方法使用来提高Map里面的搜索效率的,Map会根据不同的hashCode()来放在不同的桶里面,Map在搜索一个对象的时候先通过 hashCode()找到相应的桶,然后再根据equals()方法找到相应的对象.要正确的实现Map里面查找元素必须满足一下两个条件:?
(1)当obj1.equals(obj2)为true时obj1.hashCode() == obj2.hashCode()必须为true?
(2)当obj1.hashCode() == obj2.hashCode()为false时obj.equals(obj2)必须为false

Java中的集合(Collection)有两类,一类是List,再有一类是Set。你知道它们的区别吗?前者集合内的元素是有序的,元素可以重复;后者元素无序,但元素不可重复。
那么这里就有一个比较严重的问题了:要想保证元素不重复,可两个元素是否重复应该依据什么来判断呢?这就是Object.equals方法了。
但是,如果每增加一个元素就检查一次,那么当元素很多时,后添加到集合中的元素比较的次数就非常多了。
也就是说,如果集合中现在已经有1000个元素,那么第1001个元素加入集合时,它就要调用1000次equals方法。这显然会大大降低效率。
哈 希算法也称为散列算法,是将数据依特定算法直接指定到一个地址上。我们可以认为hashCode方法返回的就是对象存储的物理地址(实际可能并不是,例 如:通过获取对象的物理地址然后除以8再求余,余数几是计算得到的散列值,我们就认为返回一个不是物理地址的数值,而是一个可以映射到物理地址的值)。
这 样一来,当集合要添加新的元素时,先调用这个元素的hashCode方法,就一下子能定位到它应该放置的物理位置上。如果这个位置上没有元素,它就可以直 接存储在这个位置上,不用再进行任何比较了;如果这个位置上已经有元素了,就调用它的equals方法与新元素进行比较,相同的话就不存了,不相同就散列 其它的地址。所以这里存在一个冲突解决的问题。这样一来实际调用equals方法的次数就大大降低了,几乎只需要一两次。

读书人网 >编程

热点推荐