0

I have a class A with automatically generated hashCode() and equals() methods:

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

And an enumeration:

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

In my main method I have the following 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

I suppose it's the equals() method which is broken, because normally with int values instead of IntegerPropertiy the second println(...) shouldn't print null. Does anyone have an idea how to fix this?

6
  • 1
    You seem to be expecting two SimpleIntegerPropertys to be equal just because they currently hold the same value. I don't think that's the way they work. Commented Aug 29, 2021 at 17:52
  • „fs“ is used in your println, but it is not defined Commented Aug 29, 2021 at 17:54
  • This is null because you don't have a key in your map, you didn't put any a2 to your map. Commented Aug 29, 2021 at 17:56
  • 1
    You could use the value of the property in your equals and hashcode implementations. As long as you're not going to change the values of those properties while your A instance is inside the hashmap. Commented Aug 29, 2021 at 18:00
  • 1
    @AlexRudenko Guessing docs.oracle.com/javase/8/javafx/api/javafx/beans/property/… Commented Aug 29, 2021 at 18:01

1 Answer 1

1

You seem to be expecting two SimpleIntegerPropertys to be equal just because they currently hold the same value.

Going by https://docs.oracle.com/javase/8/javafx/api/javafx/beans/property/SimpleIntegerProperty.html that doesn't seem to be how they work.

Instead you could use the values from those properties in your equals and hashcode methods.

@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());
}

This way two instances of A with the same values for x and y will be equal. (However, if you alter those values while your object is a key in a hashmap, the hashmap won't work properly. That's the downside of value-based equals/hashcode implementations.)

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.