我已经为实践目的编写了下面的代码,其中为节点覆盖了equals(),这样如果两个节点n1和n2的数据相等,则它们是相等的。在下面的代码中,节点n1和n2被定义为具有相同的数据,即整数100。
还定义了节点的HashSet。我们也知道HashSet不接受重复。如果nsh和n2的数据相等,如何将这两个节点标记为n1和n2,如果n1与n1具有相同的数据,则不接受n2?
我的印象是,当调用hashSet.add(n2)时,它调用Node.equals来查看n2的副本是否已经在集合中,但我错了!
如何制作HashSet> hashSet在调用HashSet.add()时检查出现节点的数据是否有重复项?
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
}
}
答案 0 :(得分:4)
HashSet
使用equals()
和hashCode()
方法检查您是否已存在要插入的元素。您还应该覆盖hashCode()
方法。哦,注意你并没有真正重写equals(Object)
方法,而是重载它。那不是一回事。确保参数类型为Object
。还要始终在要覆盖的方法上添加@Override
注释。
答案 1 :(得分:2)
我的印象是,当调用hashSet.add(n2)时,它调用Node.equals来查看n2的副本是否已经在集合中,但我错了!
实际上,你是对的(有点)。
它调用boolean equals(Object)
方法。但是您已经使用boolean equals(Node<T>)
创建了一个重载的等于方法...并且该方法将不会被HashSet
方法调用。
写下这样的equals方法:
@Override
boolean equals(Object node) {
...
}
由于你已经重载equals
,你还需要重载int hashcode()
...或者你的hashset实例会中断。
答案 2 :(得分:0)
您应该覆盖hashCode()方法。 如果你不这样做,jvm会自动为每个对象生成hashCode,可能是通过将对象的内部地址转换为整数。
你可以打印出n1和n2的hashCode,它们是不同的:
System.out.println(n1.hashCode());
System.out.println(n2.hashCode());