使用具有 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 实现的缺点。)
我有一个 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 实现的缺点。)