How to make HashSet<T> invoking T.equals(Object ) when HashSet.add() is called [duplicate]

StackOverflow https://stackoverflow.com/questions/22728124

  •  23-06-2023
  •  | 
  •  

Question

I have written the code below for practice purposes, where the equals() is overridden for Node so that two nodes n1 and n2 are equal if their data dare equal. In the code below nodes n1 and n2 are defined having same data, which is Integer number 100.

A HashSet of Node is also defined. We also know that the HashSet does not accept duplicates. How can I make this HashSet marking two nodes n1 and n2 duplicate if their data are equal, and not accept n2 if n1 has same data as n1?

I was under the impression that when hashSet.add(n2) is called, it invokes Node.equals to see if a duplicate of n2 is already in the set, but I was wrong!.

How can I make the HashSet> hashSet check the data of the exiting Nodes for duplicates when HashSet.add() is called?

import java.util.HashSet;
public class Node<T>{
    public T data;
    public Node(T data){
        this.data = data;
    }

    boolean equals(Node<T> node){
        return this.data.equals(node.data);

    }

    public static void main(String[] args) {
        Node <Integer> n1 = new Node<>(100);
        Node <Integer> n2 = new Node<>(100);// both have same data

        HashSet<Node<Integer>> hashSet = new HashSet<>();

        System.out.println(hashSet.add(n1));
        System.out.println(hashSet.add(n2));// this should not be true as n2.equals(n1) and set does not let duplicates 
    }
}
Was it helpful?

Solution

HashSet uses both equals() and hashCode() method to check if there already exists the element you are inserting. You should also override hashCode() method. Oh, and notice that you're not really overriding equals(Object) method, but overloading it. That's not the same thing. Make sure the parameter type is Object. Also always add @Override annotation over the method that you intend to override.

OTHER TIPS

I was under the impression that when hashSet.add(n2) is called, it invokes Node.equals to see if a duplicate of n2 is already in the set, but I was wrong!.

Actually, you were correct (sort of).

It invokes the boolean equals(Object) method. But you have created a overloaded equals method with boolean equals(Node<T>) ... and that method will not be called by HashSet methods.

Write the equals method like this:

@Override
boolean equals(Object node) {
    ...
}

And since you have overloaded equals you also need to overload int hashcode() ... or your hashset instance will break.

You should override hashCode() method. If you don't do this, jvm will generate hashCode automatically for each object, maybe by converting the internal address of the object into an integer.

You can print out hashCode of n1 and n2, they are different:

System.out.println(n1.hashCode());
System.out.println(n2.hashCode());   
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top