對象作為 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.后續補充。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM