【问题标题】:HashMap get comes back with null even tho key is in it即使键在其中,HashMap get 也会返回 null
【发布时间】:2021-11-23 23:03:34
【问题描述】:

我正在尝试创建一个带有图标的挥杆棋盘,但我无法使用 HashMap 将图标放到 JButtons 上。 以下是我正在使用的类:

主类

public class GameGUI  extends JFrame {
    private JButton tiles[][] = new JButton[8][8];
    private HashMap<PieceKey, ImageIcon> icons = new HashMap<>();

    public GameGUI(){
        //swing shenannigans

        initImages();

        Tile[][] fenTiles = game.getFen().getTiles();
        for(int row = 0; row <= 7; row++){
            for(int column = 0; column <= 7; column++){
                Piece piece = fenTiles[row][column].getPiece();
                if(piece != null) {
                    tiles[row][column].setIcon(icons.get(new PieceKey(piece.getType(), piece.getColor())));
                }
            }
        }


    }

    public void initImages(){
        icons.put(new PieceKey(PieceType.pawn, Team.white), new ImageIcon("pieces/wpawn.png"));
        //.....
        }

    public static void main(String args[]){
        GameGUI asd = new GameGUI();
    }
}

PieceKey 类

public class PieceKey {
    PieceType type;  //enum
    Team color;      //enum

    public PieceKey(PieceType type, Team color) {
        this.color = color;
        this.type = type;
    }
    
    @Override
    public boolean equals(Object o){
        if(this == o)
            return true;
        if(!(o instanceof PieceType))
            return false;
        PieceKey key = (PieceKey) o;
        return this.type == key.type && this.color == key.color;
    }

    @Override
    public int hashCode(){
        return type.toString().hashCode() * color.toString().length();
    }
}

团队枚举

public enum Team {
    white, black;
}

PieceType 枚举

public enum PieceType {
    pawn, rook, knight, bishop, king, queen;
}

我的问题是每当我打电话时

icons.get(new PieceKey(piece.getType(), piece.getColor()));

它返回null,所以我不能把图标放在按钮上,如果我手动做它工作正常,所以问题出在HashMap上。我试图覆盖 PieceKey 类中的 equals 和 hashcode 函数,但它似乎不起作用。

【问题讨论】:

  • 我认为@jccampenero 发现了这个问题。但如果您使用的是最新版本的 Java,您可能需要考虑使用 record 代替 PieceKey 以避免这些问题。
  • 这是一个很好的观点@sprinter。

标签: java enums hashmap


【解决方案1】:

问题可能出在您的 PieceKey equals 方法中。你在使用instanceof时错误地使用了PieceType

@Override
public boolean equals(Object o){
    if(this == o)
        return true;
    // Please, note this, it will always return false, and the `Map`
    // `equals` method for `get` and `put` will not work
    if(!(o instanceof PieceType))
        return false;
     PieceKey key = (PieceKey) o;
     return this.type == key.type && this.color == key.color;
}

如果应该是:

@Override
public boolean equals(Object o){
    if(this == o)
        return true;
    // Please, note this
    if(!(o instanceof PieceKey))
        return false;
     PieceKey key = (PieceKey) o;
     return this.type == key.type && this.color == key.color;
}

【讨论】:

  • 谢谢你,我已经找了 5 个小时了,我想我只需要第二双眼睛就能找到它!干杯!
  • 非常欢迎您@SanyiLukácsi。我同意你的观点,我们所有人有时都需要第二双眼睛来发现问题。很高兴为您提供帮助。
【解决方案2】:

Answer by jccampanero 似乎是正确的,您在覆盖 Object :: equals 的实现细节方面存在问题。

记录

另一个解决方案是避免甚至需要编写自己的equalshashCode。如果您的 PieceKey 类主要用于透明和不可变的携带数据,则将该类定义为 record

您的整个班级都简化为这条简单的短线。

public record PieceKey ( PieceType type , Team color ) {}

作为记录,编译器隐式创建构造函数、getter、equals & hashCodetoString

创建实例的方式与使用常规类相同。

new PieceKey( PieceType.pawn , Team.white )

额外提示:在 Java 16 及更高版本中,作为创建记录功能的工作的一部分,我们现在可以在本地声明记录、枚举和接口。

【讨论】:

    【解决方案3】:

    您应该使用您的 IDE 来生成您的 hashCode 和 equals 实现。

    你应该拥有的最默认的实现应该是这样的:

    @Override
    public int hashCode() {
      return Objects.hash(type, color); // java.util.Objects
    }
    
    @Override
    public boolean equals(Object o) {
      if (o == this) return true;
      if (!(o instanceof PieceKey) return false;
      PieceKey other = (PieceKey) o;
      return Objects.equals(type, other.type)
          && Objects.equals(color, other.color);
    }
    

    请注意,对于 Java 17 记录,您根本不需要这个:

    public record PriceKey(PieceType type, Team color) {}
    
    • hashCode()equals() 是使用类型/颜色生成的。
    • typecolor 默认为 final

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-09-11
      • 2017-03-20
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多