如何在调用HashSet.add()时调用HashSet <t>调用T.equals(Object)</t>

时间:2014-03-29 07:05:55

标签: java hashmap hashset

我已经为实践目的编写了下面的代码,其中为节点覆盖了equals(),这样如果两个节点n1和n2的数据相等,则它们是相等的。在下面的代码中,节点n1和n2被定义为具有相同的数据,即整数100。

还定义了节点的HashSet。我们也知道HashSet不接受重复。如果nsh和n2的数据相等,如何将这两个节点标记为n1和n2,如果n1与n1具有相同的数据,则不接受n2?

我的印象是,当调用hashSet.add(n2)时,它调用Node.equals来查看n2的副本是否已经在集合中,但我错了!

如何制作HashSet&gt; 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 
    }
}

3 个答案:

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