使用具有 IntegerProperty 字段的对象作为 HashMap 中的键

Using objects with IntegerProperty fields as a key in a HashMap

我有一个 class A,带有自动生成的 hashCode() 和 equals() 方法:

public class A {

private IntegerProperty x = new SimpleIntegerProperty();
private IntegerProperty y = new SimpleIntegerProperty();

public Coordinate(int x, int y) {
    this.x.set(x);
    this.y.set(y);
}

public int getX() {
    return x.get();
}

public void setX(int x) {
    this.x.set(x);
}

public int getY() {
    return y.get();
}

public void setY(int y) {
    this.y.set(y);
}

@Override
public int hashCode() {
    final int prime = 31;
    int result = 1;
    result = prime * result + ((x == null) ? 0 : x.hashCode());
    result = prime * result + ((y == null) ? 0 : y.hashCode());
    return result;
}

@Override
public boolean equals(Object obj) {
    if (this == obj)
        return true;
    if (obj == null)
        return false;
    if (getClass() != obj.getClass())
        return false;
    A other = (A) obj;
    if (x == null) {
        if (other.x != null)
            return false;
    } else if (!x.equals(other.x))
        return false;
    if (y == null) {
        if (other.y != null)
            return false;
    } else if (!y.equals(other.y))
        return false;
    return true;
}
...
}

还有一个枚举:

public enum E {
S1,S2;
...
}

在我的主要方法中,我有以下 HashMap:

private ObservableMap<A, E> m = FXCollections.observableMap(new HashMap<>());
A a1 = new A(0,0);
A a2 = new A(0,0);
E e1 = E.S1;
    
m.put(a1, e1);
System.out.println(m.get(a1)); // S1
System.out.println(m.get(a2)); // null

我想是 equals() 方法被破坏了,因为通常使用 int 值而不是 IntegerPropertiy,第二个 println(...) 不应该打印 null。 有人知道如何解决这个问题吗?

您似乎期望两个 SimpleIntegerProperty 相等,只是因为它们当前具有相同的值。

https://docs.oracle.com/javase/8/javafx/api/javafx/beans/property/SimpleIntegerProperty.html 进行操作,这似乎不是他们的工作方式。

相反,您可以在 equals 和 hashcode 方法中使用这些属性的 values

@Override
public int hashCode() {
    return Objects.hash(getX(), getY());
}

@Override
public boolean equals(Object o) {
    if (this==o) return true;
    if (o==null || o.getClass()!=this.getClass()) return false;
    A that = (A) o;
    return (this.getX()==that.getX() && this.getY()==that.getY());
}

这样,具有相同 x 和 y 值的两个 A 实例将相等。 (但是,如果您更改这些值,而您的对象是散列图中的键,则散列图将无法正常工作。这是基于值的 equals/hashcode 实现的缺点。)