關於HashMap以對象作為Key的實現及踩坑


關於HashMap以對象作為Key的實現及踩坑

1 場景

今天遇到了這樣一串代碼

image-20211123001950011

對於畫圈的部分,看起來很奇怪,我一開始想改為:

result.get(groupPath).add(indexes);
groupPath.addMeasurements(exactPath.getMeasurementList());
groupPath.addSchemas(exactPath.getSchemaList());

但是卻發生了大量的空指針異常

2 原因

查看源碼后發現,HashMap以對象作為Key的時候(假設我們重寫了hashcode以及equals方法),他在put和get的時候對於key部分會處理:

  • hash(key)
  • key

image-20211123002248654

image-20211123002303759

換言之,在執行put的時候,HashMap會保存當前key對象的hash值引用,在get(key)的時候,會根據執行get時刻的key對象hash值進行查找,再根據引用判斷相等。

3 一個實驗

import java.util.*;

public class HashMapTest {
    public static void main(String[] args) {
        Map<MyObject, List> map = new HashMap<>();
        MyObject object = new MyObject("a");
        map.put(object,new ArrayList());
        object.setName("b");
        System.out.println(map.containsKey(object));
        for (MyObject myObject : map.keySet()) {
            System.out.println(myObject.hashCode());
        }
        System.out.println(object.hashCode());
        MyObject object1 = new MyObject("a");
        System.out.println(map.containsKey(object1));
        System.out.println(object1.hashCode());
        object.setName("a");
        System.out.println(map.containsKey(object));
    }

    public static class MyObject{
        String name;
        MyObject (String name){
            this.name = name;
        }

        public void setName(String name) {
            this.name = name;
        }

        @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (o == null || getClass() != o.getClass()) return false;
            MyObject myObject = (MyObject) o;
            return Objects.equals(name, myObject.name);
        }

        @Override
        public int hashCode() {
            return Objects.hash(name);
        }
    }
}

執行結果為:

false
129
129
false
128
true


免責聲明!

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



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