为什么这个HashMap.get返回一个null? [英] Why does this HashMap.get return a null?

查看:147
本文介绍了为什么这个HashMap.get返回一个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>();

//构造函数
public TestCard(){
}

public static void main(String [] args){
Card [ ]卡=新卡[3];
卡[0] =新卡((短)12,(短)0);
卡[1] =新卡((短)0,(短)1);
卡[2] =新卡((短)5,(短)2);

/ *构建SpecialK查找HashMap。
*黑桃王牌= 0
*红桃王牌= 1
*钻石王牌= 2
*俱乐部王牌= 3
* ...
*两个俱乐部= 51
* /
整数specialKCounter = 0; (int j = 0; j< 4; j ++){
specialKLookup.put(new Card(new card(i))的
(int i = 12; i> = 0; (short)i,(short)j),specialKCounter ++);
}
}

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

Card.java

 公共课卡{
私人短排,西装;

private static String [] ranking = {2,3,4,5,6,7,8,9,10 ,杰克,女王,国王,王牌};
private static String [] suit = {Spades,Hearts,Diamonds,Clubs};

//构造函数
公共卡片(短等级,短符合){
this.rank =等级;
this.suit =套装;
}

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

public short getRank(){
return rank;
}

保护无效setSuit(短套装){
this.suit =套装;
}

保护无效setRank(短等级){
this.rank =等级;
}
}


解决方案

类( Card )缺少正确的 equals(Object) hashCode()



如果没有定义它们,将不起作用。 (它编译得很好,因为这些方法都是虚拟的,并且在所有对象中都是继承的,因为它们是Object的一部分:HashMap无法在编译时强制执行此操作。)请参阅上面的链接,了解所需的合同。



这两种方法都需要实现,因为 hashCode 确定HashMap实现中使用的哈希桶, equals 是为了确保一个对象是value-equals(多个对象可以具有相同的 hashCode ,这就是为什么等于也是必需的)。请参阅哈希表以获取更一般的哈希详细信息。



如果这些方法没有被重载,那么使用在Object中定义的实现。也就是说, x.equals(y)接近 - x == y 语义和 hashCode 为每个合约返回一个稳定的数字。这有效地使地图像一个身份地图一样工作(当Card对象是键时):只有完全相同的对象可以检索以前存储的值 - 每隔一个get都会返回如观察到的那样。

愉快的编码。


I'm trying to create a Hashmap to perform a lookup for me. However when I run this test code, the output is null. I think it has to due with the nature of how the keys are being stored, but Im not positive. Maybe it's a similar quirk like how the var1 == var2 are not equals unless they point to the same Object in memory, instead you have to use the var1.equals(var2)?

There are two classes to test this.

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;
    }   
}

解决方案

The class (Card) is missing a proper implementation of equals(Object) and hashCode()

Without both of these defined it will just not work. (It compiles fine because these methods are both virtual and inherited in all objects as they are part of Object: HashMap can't enforce this at compile-time.) See the links above for the contract that is required.

Both of these methods are required to be implemented because hashCode determines the hash-bucket used in the HashMap implementation and equals is to ensure that an object is value-equals (multiple objects can have the same hashCode, which is why equals is also required). See Hash table for more general hash details.

If these methods are not overloaded then the implementations defined in Object are used. That is, x.equals(y) has near-x == y semantics and hashCode returns a stable number per contract. This effectively makes the map work like an identity map (when Card objects are keys): only the exact same object can retrieve a previously stored value -- every other get will return null, as observed.

Happy coding.

这篇关于为什么这个HashMap.get返回一个null?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆