在java中使用PriorityQueue.contains()的问题

时间:2014-04-12 18:10:27

标签: java collections

我正在Java中测试Min-PriorityQueue的功能。这就是我实现它的方式。但是在运行时,.contains()为对象返回false,我相信它存在于数据结构中。任何有关这出错的见解?

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


        }

    }

输出显示:

          Is Present : false
          FName, LName, age : Ron,Weasley,14

3 个答案:

答案 0 :(得分:3)

您应该使用equals()参数显式覆盖Object方法。您的equals()方法不是Object#equals()的重写版本,它是一个重载版本。 Java集合在其操作上调用equals(),并在您的情况下调用super.equals(),而不是您的实现。

修改

现在我还检查了除签名之外的equals()实现。使用equals()比较字符串字段,而不是==运算符。

答案 1 :(得分:0)

除了接受的答案外,您还必须在compareToequals方法中保持一致,才能正确实施Comparable界面:

  

当且仅当e1.compareTo(e2)== 0与c1的每个e1和e2的e1.equals(e2)具有相同的布尔值时,C类的自然排序被认为与equals一致。请注意,null不是任何类的实例,并且e.compareTo(null)应该抛出NullPointerException,即使e.equals(null)返回false。

例如:

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

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

由于这种不一致性,这些对象在任何有序Collection中都不会按预期运行。当两个节点具有相同的年龄时,您可能希望更改compareTo方法以在名称字段上使用词典排序。

答案 2 :(得分:0)

您应该显式重写equals()方法。

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