今天用到了HashMap,HashMap<GPSPoint, Integer>
但是当新建另外一个GPSPoint的时候却取不到对应的value
Map<GPSPoint, Integer> map=new HashMap<GPSPoint, Integer>(); for(int i=0;i<5;i++){ GPSPoint p=new GPSPoint(i,i,i,i); map.put(p, i); } GPSPoint p=new GPSPoint(2,2,2,2); int i=map.get(p); System.out.println(i);
而hashMap通过key查找是找hashCode
更加深入了解,请见另外一篇 深入解析Java对象的hashCode和hashCode在HashMap的底层数据结构的应用
重写hashCode()时最重要的原因就是:
无论何时,对同一个对象调用hashCode()都应该生成同样的值。如果在将一个对象用put()方法添加进HashMap时产生一个hashCode()值,而用get()取出时却产生了另外一个 hashCode()值,那么就无法重新取得该对象了。所以,如果你的hashCode()方法依赖于对象中易变的数据,那用户就要小心了,因为此数据发生变化时,hashCode()就会产生一个不同的hash码,相当于产生了一个不同的“键”。 Object的hashCode()方法,返回的是当前对象的内存地址。下次如果我们需要取一个一样的“键”对应的键值对的时候,我们就无法得到一样的hashCode值了。因为我们后来创建的“键”对象已经不是存入HashMap中的那个内存地址的对象了。
下面看看怎么重写hashCode
1、我们应该先了解java判断两个对象是否相等的规则。
在java的集合中,判断两个对象是否相等的规则是:
1 首先,判断两个对象的hashCode是否相等
2 如果不相等,认为两个对象也不相等
3 如果相等,则判断两个对象用equals运算是否相等
4 如果不相等,认为两个对象也不相等
5 如果相等,认为两个对象相等
我们在equals方法中需要向下转型,效率很低,所以先判断hashCode方法可以提高效率
(1)为对象内每个有意义的属性f(即每个用作equals()比较标准的属性)计算出一个int类型的hashCode值。计算方法如下表所示: 属性类型 计算方式 boolean hashCode = (f ? 0 : 1); 整数类型(byte、short、char、int) hashCode = (int)f; long hashCode = (int)(f ^ (f >>>32)); float hashCode = Float.floatToIntBits(f); double long l = Double.doubleToLongBits(f); hashCode = (int)(l ^ (l >>> 32)); 普通引用类型 hashCode = f.hashCode(); (2)使用第1步计算出来多个hashCode组合计算出一个hashCode值返回。例如如下代码: return f1.hashCode() + (int)f2; 如果为了避免直接相加产生偶然相等(两个对象的f1、f2属性并不相等,但他们的和恰好相等),可以通过为各属性乘以任意一个质数后再相加。例如如下代码: return f1.hashCode() * 17+ (int)f2 * 13;