1,hasCode,一般用于快捷查询对象的,比如散列存储的HashSet;每个对象会返回不同的整数,不过可能会出现相同值,虽然概率很少。为避免这种想象,所以需要equals啦
2,equals,判断对象是否相等,包括hasCode;通过equals得出两个对象相等,那么hasCode必定相等;如果equals不相等,hasCode有可能不同,也可能相同
具体说明:
HashSet在添加子对象时,会首先调用hasCode,判断是否存在该对象,如果hasCode不同,则表示不同的对象;如果hasCode相同,再去调用equals判断是否存在改对象;
由此可知,hashCode方法是为了减少equals方法的调用次数,从而提高程序效率,即快捷查询对象。
public V put(K key, V value) { if (key == null) return putForNullKey(value); int hash = hash(key.hashCode()); int i = indexFor(hash, table.length); for (Entrye = table[i]; e != null; e = e.next) { Object k; if (e.hash == hash && ((k = e.key) == key || key.equals(k))) { V oldValue = e.value; e.value = value; e.recordAccess(this); return oldValue; } } modCount++; addEntry(hash, key, value, i); return null; }
HashSet的get对象方法也采用类似的机制,会先调用hasCode再调用equals
public V get(Object key) { if (key == null) return getForNullKey(); int hash = hash(key.hashCode()); for (Entrye = table[indexFor(hash, table.length)]; e != null; e = e.next) { Object k; if (e.hash == hash && ((k = e.key) == key || key.equals(k))) return e.value; } return null; }
注意事项:
在重写equals时,也要重写hasCode
我们在重写equals时,觉得已经相同了,但是hasCode函数还是不同的。
HashSet在add对象时先根据hasCode判断对象,hasCode不同,所以对象不同,HaspMap会保存两个对象,即使equals相同
import java.util.HashSet; import java.util.Set; public class HashTest { private int i; public int getI() { return i; } public void setI(int i) { this.i = i; } public boolean equals(Object object) { if (object == null) { return false; } if (object == this) { return true; } if (!(object instanceof HashTest)) { return false; } HashTest other = (HashTest) object; if (other.getI() == this.getI()) { return true; } return false; } public final static void main(String[] args) { HashTest a = new HashTest(); HashTest b = new HashTest(); a.setI(1); b.setI(1); Setset = new HashSet (); set.add(a); set.add(b); System.out.println("a.hasCode="+a.hashCode()); System.out.println("b.hasCode="+ b.hashCode()); System.out.println("a.equals(b)="+a.equals(b)); System.out.println("set:"+set); } }
a.hasCode=1794515827 b.hasCode=1167165921 a.equals(b)=true set:[com.chinaunicom.rp.rpTemplate.web.action.HashTest@6af62373, com.chinaunicom.rp.rpTemplate.web.action.HashTest@459189e1]
正确做法时,重写equals同时重写hasCode
package com.chinaunicom.rp.rpTemplate.web.action; import java.util.HashSet; import java.util.Set; public class HashTest { private int i; public int getI() { return i; } public void setI(int i) { this.i = i; } public boolean equals(Object object) { if (object == null) { return false; } if (object == this) { return true; } if (!(object instanceof HashTest)) { return false; } HashTest other = (HashTest) object; if (other.getI() == this.getI()) { return true; } return false; } public int hashCode() { return i % 10; } public final static void main(String[] args) { HashTest a = new HashTest(); HashTest b = new HashTest(); a.setI(1); b.setI(1); Setset = new HashSet (); set.add(a); set.add(b); System.out.println("a.hasCode="+a.hashCode()); System.out.println("b.hasCode="+ b.hashCode()); System.out.println("a.equals(b)="+a.equals(b)); System.out.println("set:"+set); } }
a.hasCode=1 b.hasCode=1 a.equals(b)=true set:[com.chinaunicom.rp.rpTemplate.web.action.HashTest@1]
Leave a Reply