对象作为 map 的 key 时,需要重写 equals 方法和 hashCode 方法

对象作为 map 的 key 时,需要重写 hashCode 和 equals方法

如果没有重写 hashCode 方法,那么下面的代码示例会输出 null

我们首先定义一个对象:BmapPoint,假如这个对象只重写了 equals 方法,没有重写 hashCode 方法

package mm_test;

/**
 * @Function: TODO ADD FUNCTION. <br/>
 * @Date: 2016年3月7日 下午4:29:23
 * 
 * @author zhangmengmeng01@baidu.com
 */
public class BmapPoint {

    // 经度
    private double lng;

    // 纬度
    private double lat;

    public BmapPoint() {
    }

    public BmapPoint(double lng, double lat) {
        this.lng = lng;
        this.lat = lat;
    }

    public boolean equals(Object obj) {
        if (obj instanceof BmapPoint) {
            BmapPoint bmapPoint = (BmapPoint) obj;
            return (bmapPoint.getLng() == lng && bmapPoint.getLat() == lat) ;
        } else {
            return false;
        }
    }

    public double getLng() {
        return lng;
    }

    public void setLng(double lng) {
        this.lng = lng;
    }

    public double getLat() {
        return lat;
    }

    public void setLat(double lat) {
        this.lat = lat;
    }
}
View Code

那么我的测试 main 方法如下:

package mm_test;

import java.util.HashMap;
import java.util.Map;

/**
 * @Function: TODO ADD FUNCTION. <br/>
 * @Date: 2016年3月7日 下午4:29:57
 * 
 * @author zhangmengmeng
 */
public class testsBmapPoint {
    public static void main(String[] args) {
        Map<BmapPoint, Long> bmap = new HashMap<BmapPoint, Long>();
        
        BmapPoint bp1 = new BmapPoint(3.14, 3.25);
        BmapPoint bp2 = new BmapPoint(3.14, 3.25);
        bmap.put(bp2, (long) 2);

        System.out.println(bmap.get(bp1));
        System.out.println(bmap.get(bp2));
    }
}

输出结果:

3.25

3.25

null

2

 解释:bp1和 bp2的内容一样,但不是同一个实例,我把 bp2放到 map 中了,如果用 bp1作为 key 去获取对应的 value 值,得到的结果为 null。

下面我重写 BmapPoint 的 hashCode 方法,在类 BmapPoint 中加入如下代码:

    public int hashCode() {
        return new Double(lng).hashCode() + new Double(lat).hashCode();
    }

然后再运行主函数,输入结果:

3.25

3.25

2

2

这次就能 get 到对应的 value 值了。

原理可以参见博客:http://blog.csdn.net/benjaminzhang666/article/details/9468605

然后碰巧我看到了《effective java》中的第9条:

覆盖 equals 是总要覆盖 hashCode

如果不这样做,就会违反 Object.hashCode 的通用约定,从而导致该类无法结合所有基于散列的集合一起正常运作,这样的集合包括 HashMap、HashSet 和 HashTable……

具体内容参见《effective java》P39.后续补充。

 

原文地址:https://www.cnblogs.com/sonofelice/p/5251093.html