首先说建议的情况:? 比如你的对象想放到Set集合或者是想作为Map的key时(非散列的Set和Map,例如TreeSet,TreeMap等),那么你必须重写equals()方法,这样才能保证唯一性。当然,在这种情况下,你不想重写hashCode()方法,也没有错。但是,对于良好的编程风格而言,你应该在重写equals()方法的同时,也重写hashCode()方法。?
然后再说说必须重写hashCode()的情况:?
??? 如果你的对象想放进散列存储的集合中(比如:HashSet,LinkedHashSet)或者想作为散列Map(例如:HashMap,LinkedHashMap等等)的Key时,在重写equals()方法的同时,必须重写hashCode()方法。?
这里我想讲讲sun的设计者为什么需要设计hashcode方法,也许这样你就应该知道什么时候该重写它了。?
数据结构有一种为了提高查找的效率而存在的数据结构——散列表,散列表其实是普通数组概念的推广,因为可以对数组进行直接寻址,故可以再O(1)时间内访问数组的任意元素,thinking in java中有个对hashmap简单的实现,我们来看看你就明白了:?
?
class="dp-j">
- ??
- ??
- import?java.util.*;??
- import?net.mindview.util.*;??
- ??
- public?class?SimpleHashMap<K,V>?extends?AbstractMap<K,V>?{??
- ????
- ????
- ??static?final?int?SIZE?=?997;??
- ????
- ????
- ??@SuppressWarnings("unchecked")??
- ??LinkedList<MapEntry<K,V>>[]?buckets?=??
- ????new?LinkedList[SIZE];?
- ??public?V?put(K?key,?V?value)?{
- ????V?oldValue?=?null;??
- ????int?index?=?Math.abs(key.hashCode())?%?SIZE;
- ????if(buckets[index]?==?null)??
- ??????buckets[index]?=?new?LinkedList<MapEntry<K,V>>();?
- ????LinkedList<MapEntry<K,V>>?bucket?=?buckets[index];
- ????MapEntry<K,V>?pair?=?new?MapEntry<K,V>(key,?value);??
- ????boolean?found?=?false;??
- ????ListIterator<MapEntry<K,V>>?it?=?bucket.listIterator();??
- ????while(it.hasNext())?{??
- ??????MapEntry<K,V>?iPair?=?it.next();??
- ??????if(iPair.getKey().equals(key))?{?
- ????????oldValue?=?iPair.getValue();??
- ????????it.set(pair);???
- ????????found?=?true;??
- ????????break;??
- ??????}??
- ????}??
- ????if(!found)??
- ??????buckets[index].add(pair);
- ????return?oldValue;??
- ??}??
- ??public?V?get(Object?key)?{?
- ????int?index?=?Math.abs(key.hashCode())?%?SIZE;[color=red]??
- ????if(buckets[index]?==?null)?return?null;
- ????for(MapEntry<K,V>?iPair?:?buckets[index])
- ??????if(iPair.getKey().equals(key))??
- ????????return?iPair.getValue();??
- ????return?null;??
- ??}??
- ??public?Set<Map.Entry<K,V>>?entrySet()?{??
- ????Set<Map.Entry<K,V>>?set=?new?HashSet<Map.Entry<K,V>>();??
- ????for(LinkedList<MapEntry<K,V>>?bucket?:?buckets)?{??
- ??????if(bucket?==?null)?continue;??
- ??????for(MapEntry<K,V>?mpair?:?bucket)??
- ????????set.add(mpair);??
- ????}??
- ????return?set;??
- ??}??
- ??public?static?void?main(String[]?args)?{??
- ????SimpleHashMap<String,String>?m?=??
- ??????new?SimpleHashMap<String,String>();??
- ????m.putAll(Countries.capitals(25));??
- ????System.out.println(m);??
- ????System.out.println(m.get("ERITREA"));??
- ????System.out.println(m.entrySet());??
- ??}??
- }??
- ?
- ?
- ?
?
怎样?现在应该知道hashcode方法的作用了吧,它就是用来提高效率的,有句话说得好:为速度而散列。因为散列的Set和Map是基于hashcode方法来查找对象的,所以你在使用这些类的时候一定要覆盖hashcode方法,而非散列的Set和Map,例如TreeSet,TreeMap等,它们只需equals方法就可以唯一确定对象的身份。这样说,想必已经很清楚了吧。
转:?http://blog.csdn.net/huxin1/article/details/6325051