我正在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
答案 0 :(得分:3)
您应该使用equals()
参数显式覆盖Object
方法。您的equals()
方法不是Object#equals()
的重写版本,它是一个重载版本。 Java集合在其操作上调用equals()
,并在您的情况下调用super.equals()
,而不是您的实现。
修改强>
现在我还检查了除签名之外的equals()
实现。使用equals()
比较字符串字段,而不是==
运算符。
答案 1 :(得分:0)
除了接受的答案外,您还必须在compareTo
和equals
方法中保持一致,才能正确实施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));
}