0

I was testing the functionality of Min-PriorityQueue in Java. This is how I implemented it. But at runtime, .contains() return false for an object, I believe is present in the data-structure. Any insights where this is going wrong ?

    public class NodeStruct implements Comparable<NodeStruct>{

        public String FName;
        public String LName;
        public int age;

        public NodeStruct(String fname, String lName, int age){
            this.FName = fname;
            this.LName = lName;
            this.age = age;
        }
        @Override
        public int compareTo(NodeStruct that) {
            return (this.age - that.age);
        }


        public boolean equals(NodeStruct obj){
            return (obj.age == this.age && obj.FName.equals(this.FName) && obj.LName.equals(this.LName));
        }

        public void print(){
            System.out.println("FName, LName, age : " + this.FName + "," + this.LName + "," + this.age);
        }

    }



    import java.util.*;
    import java.lang.*;
    import java.io.*;

    /* Name of the class has to be "Main" only if the class is public. */
    public class Main
    {

        public static void main (String[] args) throws java.lang.Exception
        {


            PriorityQueue<NodeStruct> PQ = new PriorityQueue<NodeStruct>(5);

            NodeStruct tmp = new NodeStruct("Harry", "Potter", 15);
            PQ.offer(tmp);

            tmp = new NodeStruct("Ron", "Weasley", 14);
            PQ.offer(tmp);

            tmp = new NodeStruct("Hermione", "Granger", 16);
            PQ.offer(tmp);



            boolean isPresent = PQ.contains(new NodeStruct("Ron", "Weasley", 14));

            System.out.println("Is Present : " + isPresent);

            NodeStruct tmp2 = PQ.peek();
            tmp2.print();


        }

    }

The output shows :

          Is Present : false
          FName, LName, age : Ron,Weasley,14
user35155
  • 3
  • 1
  • 3

3 Answers3

3

You should explicitly override equals() method with an Object parameter. Your equals() method is not an overridden version of Object#equals(), it is an overloaded version. And Java collections call equals() on their operations, and super.equals() is called in your case, not your implementaton.

Edit:

Now I also checked your equals() implementation besides signature. Use equals() for the comparison of String fields, not == operator.

Juvanis
  • 25,802
  • 5
  • 69
  • 87
0

In addition to the accepted answer, you must also have consistency in the compareTo and equals methods in order to correctly implement the Comparable interface:

The natural ordering for a class C is said to be consistent with equals if and only if e1.compareTo(e2) == 0 has the same boolean value as e1.equals(e2) for every e1 and e2 of class C. Note that null is not an instance of any class, and e.compareTo(null) should throw a NullPointerException even though e.equals(null) returns false.

For example:

NodeStruct n1 = new NodeStruct("Harry", "Potter", 15);
NodeStruct n2 = new NodeStruct("Hermione", "Granger", 15);

// n1.compareTo(n2) == 0
// but
// n1.equals(n2) == false

Because of this inconsistency, these objects will not behave as expected in any ordered Collection. You may want to change the compareTo method to use lexicographical ordering on the name fields when two nodes have the same age.

Joe Coder
  • 4,498
  • 31
  • 41
0

You should explicitly override equals() method.

@Override
public boolean equals(Object that){
    NodeStruct obj = (NodeStruct) that;
    return (obj.age == this.age && obj.FName.equals(this.FName) && obj.LName.equals(this.LName));
}