使用對象作為hashMap的鍵,需要覆蓋hashcode和equals方法


1:HashMap可以存放鍵值對,如果要以對象(自己創建的類等)作為鍵,實際上是以對象的散列值(以hashCode方法計算得到)作為鍵。hashCode計算的hash值默認是對象的地址值。

      這樣就會忽略對象的內容,不是以對象的內容來判斷。如果要以對象的內容進行判斷,就要覆蓋掉對象原有的hashCode方法。

  另外HashMap是以equals方法判斷當前的鍵是否與表中存在的鍵是否相同,所以覆蓋hashCode方法之后,還不能正常運行。還要覆蓋equals方法

先判斷hash(hash函數)值是否相同,相同了說明某個位置上有多個元素,再用equals(線性查找)方法判斷。

來看下面一個天氣預報系統的例子:

2:創建一個作為HashMap的鍵的對象Groundhog(土拔鼠)與Prediction(預報)對象聯系起來,

    

package chapter17.nine;

public class Groundhog {
    protected int number;
    public Groundhog(int n) {
        // TODO Auto-generated constructor stub
        number=n;
    }
    @Override
    public String toString() {
        // TODO Auto-generated method stub
        return "Groundhog #"+number;
    }
}


package chapter17.nine;

import java.util.Random;

public class Prediction {

    private static Random random=new Random();  //傳遞進參數,創建的隨機數將會相同
    private boolean shadow=random.nextDouble()>0.5;
    @Override
    public String toString() {
        // TODO Auto-generated method stub
        if(shadow){
            return "Six more weeks of Winter!";
        }else{
            return "Early Spring";
        }
    }
    
}


3:創建一個測試類

     

public class SpringDetector {

    public static <T extends Groundhog> void detectSpring(Class<T> type) throws Exception, IllegalAccessException, IllegalArgumentException, InvocationTargetException{
        Constructor<T> ghog=type.getConstructor(int.class);  //含有int參數的構造函數
        Map<Groundhog, Prediction> map=new HashMap<Groundhog, Prediction>();
        for (int i = 0; i < 10; i++) {
            map.put(ghog.newInstance(i), new Prediction());
        }
        System.out.println("map="+map);
        Groundhog gh=ghog.newInstance(3);
        System.out.println("Looking up prediction for "+gh);
        if(map.containsKey(gh)){  //map是根據對象生成的hascode地址判斷對象是否相同的,
            //如果想讓對象作為map的鍵,來判斷對象是否相同。那么對象應該覆蓋hashcode和equals方法。生成對象自己的hashcode嗎。
            //例如按照對象包含的int屬性生成hashcode 嗎等。HashMap使用equals判斷當前的鍵是否與表中存在的鍵相同。所以要覆蓋equals方法
            System.out.println(map.get(gh));
        }else{
            System.out.println("Key not found"+gh);
        }
    }
    public static void main(String[] args) {
        try {
            detectSpring(Groundhog.class);
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}


  測試結果:

map={Groundhog #1=Six more weeks of Winter!, Groundhog #4=Six more weeks of Winter!, Groundhog #5=Six more weeks of Winter!, Groundhog #3=Early Spring, Groundhog #8=Six more weeks of Winter!, Groundhog #7=Six more weeks of Winter!, Groundhog #0=Early Spring, Groundhog #2=Early Spring, Groundhog #9=Six more weeks of Winter!, Groundhog #6=Early Spring}
Looking up prediction for Groundhog #3
Key not foundGroundhog #3


  我們發現,map中並不包含Groundhog gh=ghog.newInstance(3);的鍵,可是實際上map中又添加了ghog.newInstance(3)的鍵。這是為什么呢?

  因為實際上判斷的對象的hash值。所有造成:第一個ghog.newInstance(3)的hash值不等於第二個ghog.newInstance(3)的hash值;

4:重寫Groundhog並覆蓋hashCode方法和equals方法

    

package chapter17.nine;

public class Groundhog2 extends Groundhog{

    public Groundhog2(int n) {
        super(n);
        // TODO Auto-generated constructor stub
    }
    @Override
    public int hashCode() {
        // TODO Auto-generated method stub
        return number;
    }
    @Override
    public boolean equals(Object obj) {
        // TODO Auto-generated method stub
        return obj instanceof Groundhog2 && number==((Groundhog2)obj).number;
    }
}

5:測試。

   

package chapter17.nine;

import java.lang.reflect.InvocationTargetException;

public class SpringDetector2 {

    public static void main(String[] args) {
        try {
            SpringDetector.detectSpring(Groundhog2.class);
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

6:測試結果。

    

map={Groundhog #0=Six more weeks of Winter!, Groundhog #1=Early Spring, Groundhog #2=Early Spring, Groundhog #3=Early Spring, Groundhog #4=Early Spring, Groundhog #5=Six more weeks of Winter!, Groundhog #6=Early Spring, Groundhog #7=Early Spring, Groundhog #8=Early Spring, Groundhog #9=Six more weeks of Winter!}
Looking up prediction for Groundhog #3
Early Spring


   第一個ghog.newInstance(3)的hash值等於第二個ghog.newInstance(3)的hash值。定義作為HashMap鍵的對象成功。

    


免責聲明!

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



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