簡體   English   中英

為什么這個HashMap.get返回null?

[英]Why does this HashMap.get return a null?

我正在嘗試創建一個Hashmap來為我執行查找。 但是,當我運行此測試代碼時,輸​​出為空。 我認為它必須與密鑰的存儲方式有關,但我並不積極。 也許這是一個類似的怪癖,就像var1 == var2不等於它們,除非它們指向內存中的同一個對象,而你必須使用var1.equals(var2)

有兩個類可以測試它。

TestCard.java

import java.util.HashMap;

public class TestCard {

     // HashMap for SpecialK Lookup
    private static HashMap<Card, Integer> specialKLookup = new HashMap<Card, Integer>();

    // Constructor
    public TestCard(){
    }

    public static void main(String[] args) {
        Card[] cards = new Card[3];
        cards[0] = new Card((short)12, (short)0);
        cards[1] = new Card((short)0, (short)1);
        cards[2] = new Card((short)5, (short)2);

        /* Build SpecialK Lookup HashMap.
         * Ace of Spades = 0
         * Ace of Hearts = 1
         * Ace of Diamonds = 2
         * Ace of Clubs = 3
         * ...
         * Two of Clubs = 51
         */
        Integer specialKCounter = 0;
        for(int i=12;i>=0;i--){
                for (int j=0;j<4;j++){
                        specialKLookup.put(new Card((short)i, (short)j), specialKCounter++);
                }
        }

        System.out.println(specialKLookup.get(cards[0]));
    }
}

Card.java

public class Card{
    private short rank, suit;

    private static String[] ranks = {"2", "3", "4", "5", "6", "7", "8", "9", "10", "Jack", "Queen", "King", "Ace"};
    private static String[] suits = {"Spades", "Hearts", "Diamonds", "Clubs"};

    //Constructor
    public Card(short rank, short suit){
        this.rank = rank;
        this.suit = suit;
    }

    // Getter and Setters
    public short getSuit(){
        return suit;
    }

    public short getRank(){
        return rank;
    }

    protected void setSuit(short suit){
        this.suit = suit;
    }

    protected void setRank(short rank){
        this.rank = rank;
    }   
}

類( Card )缺少equals(Object)hashCode()的正確實現

如果沒有這兩個定義, 它將無法正常工作 (它編譯得很好,因為這些方法都是虛擬的,並且在所有對象中都是繼承的,因為它們是Object的一部分:HashMap在編譯時不能強制執行此操作。)請參閱上面的鏈接以獲取所需的合同。

這兩個方法都需要實現,因為hashCode確定HashMap實現中使用的hash-bucket, equals是確保對象是value-equals(多個對象可以具有相同的hashCode ,這也是為什么還需要equals ) 。 有關更多常規哈希詳細信息,請參閱哈希表

如果這些方法沒有重載,則使用Object中定義的實現。 也就是說, x.equals(y)具有near- x == y語義, hashCode每個合約返回一個穩定的數字。 這有效地使地圖像身份地圖一樣工作(當Card對象是鍵時):只有完全相同的對象才能檢索先前存儲的值 - 每個其他get將返回null,如所觀察到的那樣。

快樂的編碼。

確實正是因為這個問題。

您需要定義卡上的相等性,因此您需要覆蓋equalshashCode方法。

如果不這樣做,則假定兩張牌只是相同的,如果他們是同一個實例。 (與equals的默認行為一樣。)

請注意,覆蓋equalshashCode非常重要,因為兩個相等的對象必須散列到相同的值才能使HashMap正常工作。

有關更多信息,請參閱在Java中覆蓋equals和hashCode

也許它類似於var1 == var2不等於的速度,除非它們指向內存中的>相同的Object,而是必須使用var1.equals(var2)

幾乎。 正如您所料,哈希映射需要一種獲取對象哈希碼的方法。 在Java中,這是由Object實現的hashCode方法提供的,但需要由Card類覆蓋。

*更新:正如pst指出的那樣,它也必須重新實現等於。

您需要實現hashCode和equals方法,因為這允許在兩個不同的對象上進行相等性測試,並且還有助於哈希映射存儲。 如果不實現這些,即使它們的屬性相同,也會看到兩個對象是不同的。 有關詳細信息,請參見http://www.jchq.net/certkey/0902certkey.htm

卡應該覆蓋equalshashCode 看看這里: http//www.ibm.com/developerworks/java/library/j-jtp05273/index.html

你必須覆蓋CardhashCode()方法並使其返回相同的值,當且僅當卡片相等時 - 你也應該重寫equals() 因為這是HashMap依賴的,以便找到鍵引用的對象; 就像現在一樣,它是繼承自Object的那些方法的版本,只有當你使用相同的對象作為鍵時,才會匹配,而你創建新的,雖然是“相等”的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM