URL87
URL87

Reputation: 11022

contains method ignores equals override

Having Node abstract class which Cell extends him .

In Cell I implemented public boolean equals(Node cmpCell) . I created Set<Node> closeList = new HashSet<Node>(); and when I execute closeList.contains((Cell) node) I debugged it and detect that it utterly ignores Cell equals I implemented . What I did wrong ?

Edit :

I changed in Cell to

@Override
public boolean equals(Object cmpCell)

and still closeList.contains((Cell) node) doesn't using the above override .

2nd Edit :

In Cell class there is 2 members -

int colIndex ;
int rowIndex ;

the equals override just compare them to that both members of the 2nd class , I think it would be better I use HashMap<K, V> but still I would be glade to know how the hashCode should be looks like in such case ?

Upvotes: 3

Views: 1942

Answers (4)

Andy
Andy

Reputation: 1994

As already stated, hashCode and equals must be implemented accordingly.

But the question asked here is "Why isn't the custom equals() called?". So, the answer is, that Java doesn't support multiple dispatch.

Simple example

If you declare Object myCell = new Cell(), then myCell2.equals(myCell) can only determine the declared type of myCell, which is Object.

Your case

The signature of the called methods is: HashSet.contains(Object o), with the same consequences as stated above.

You can do something like that, although it isn't a nice solution:

public class Cell {
    @Override
    public boolean equals(Object o) {
        if(o instanceof Cell) {
            // your code
        }

        super.equals(o);
    }
}

Upvotes: 0

Rohit Jain
Rohit Jain

Reputation: 213311

public boolean equals(Node cmpCell)

This is not a valid override. The syntax of equals method of Object class is: -

public boolean equals(Object)

And yes, as pointed out by @JonSkeet in comment, whenever you are overriding equals method, also remember to override hashCode method to follow the contract of equals and hashCode. Because if you don't do that, then even if your equals method shows evaluates your instances as equal, the default hashCode implementation in Object class will generate different hashCodes for them, and hence they won't be equal.

Also, ensure that, while calculating hashcode, you consider only those attributes, that you used to compare your instances in equals method. Else, again you will get incorrect result.

In addition to that, if you are using any IDE like Eclipse, it generates a very nicely overridden and compatible equals and hashCode method for you. You should be better using them. You need to right-click on your class, go to source and select Generate equals and hashCode method.

Upvotes: 11

Stephen Connolly
Stephen Connolly

Reputation: 14116

Well there are three potential issues:

  1. You overrode the wrong signature. Should be public boolean equals(Object)

  2. If you override equals you must implement hashCode

  3. Is your equals method symmetric (x.equals(y) implies y.equals(x)) and does it play correctly with polymorphism, ie can you have a Node.equals(Cell) but the reverse be false?

Upvotes: 1

Denys S&#233;guret
Denys S&#233;guret

Reputation: 382274

You probably didn't override the hashCode method.

An object in a hashset is found using the hashcode first. You must always override both or none of the two equals and hashCode methods.

Upvotes: 1

Related Questions