HashMap get 返回 null,即使其中有键
HashMap get comes back with null even tho key is in it
我正在尝试创建一个带有图标的摇摆棋盘,但我无法使用 HashMap 将图标放到 JButton 上。
以下是我正在使用的 classes:
主要Class
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();
}
}
PieceKeyclass
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()));
它 return 为 null,所以我不能将图标放在按钮上,如果我手动操作它会很好,所以问题出在 HashMap 上。我试图覆盖 PieceKey class 中的 equals 和 hashcode 函数,但它似乎不起作用。
问题可能出在您的 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;
}
关于您对 Object :: equals
的实现细节有疑问的 似乎是正确的。
记录
另一个解决方案是避免甚至需要编写您自己的 equals
和 hashCode
。如果您的 PieceKey
class 主要用于透明且不可变的携带数据,请将 class 定义为 record.
你的整个 class 减少到这条简单的短线。
public record PieceKey ( PieceType type , Team color ) {}
作为记录,编译器隐式创建了构造函数、getter、equals
& hashCode
和 toString
.
您可以使用与常规 class 相同的方式创建实例。
new PieceKey( PieceType.pawn , Team.white )
额外提示:在 Java 16 及更高版本中,作为创建记录功能所做工作的一部分,我们现在可以在本地声明记录、枚举和接口。
您应该使用 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()
是使用 type/color 生成的。
type
和color
默认为final
。
我正在尝试创建一个带有图标的摇摆棋盘,但我无法使用 HashMap 将图标放到 JButton 上。 以下是我正在使用的 classes:
主要Class
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();
}
}
PieceKeyclass
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()));
它 return 为 null,所以我不能将图标放在按钮上,如果我手动操作它会很好,所以问题出在 HashMap 上。我试图覆盖 PieceKey class 中的 equals 和 hashcode 函数,但它似乎不起作用。
问题可能出在您的 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;
}
关于您对 Object :: equals
的实现细节有疑问的
记录
另一个解决方案是避免甚至需要编写您自己的 equals
和 hashCode
。如果您的 PieceKey
class 主要用于透明且不可变的携带数据,请将 class 定义为 record.
你的整个 class 减少到这条简单的短线。
public record PieceKey ( PieceType type , Team color ) {}
作为记录,编译器隐式创建了构造函数、getter、equals
& hashCode
和 toString
.
您可以使用与常规 class 相同的方式创建实例。
new PieceKey( PieceType.pawn , Team.white )
额外提示:在 Java 16 及更高版本中,作为创建记录功能所做工作的一部分,我们现在可以在本地声明记录、枚举和接口。
您应该使用 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()
是使用 type/color 生成的。type
和color
默认为final
。