2014-03-29 20 views
0

爲了實踐目的,我已經編寫了下面的代碼,其中equals()被重寫爲Node,以便兩個節點n1和n2是如果他們的數據不相上下,就是相等在下面的代碼中,節點n1和n2被定義爲具有相同的數據,其是整數100.如何使HashSet <T>在調用HashSet.add()時調用T.equals(Object)

還定義了節點的HashSet。我們也知道HashSet不接受重複。如何讓這個HashSet標記兩個節點n1和n2如果他們的數據是相同的,並且如果n1的數據與n1相同則不接受n2?

我的印象是,當調用hashSet.add(n2)時,它會調用Node.equals來查看n2的重複是否已經在該集合中,但我錯了!

當HashSet.add()被調用時,如何使HashSet> hashSet檢查退出節點的數據是否重複?

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 
    } 
} 
+1

哪裏是你的'等於(對象)'?我只看到'equals(Node)'而且不會被調用。 –

回答

4

HashSet同時使用equals()hashCode()方法來檢查是否已經存在要插入的元素。您還應該覆蓋hashCode()方法。哦,並注意到你並不是真的壓倒equals(Object)方法,而是重載它。這不是一回事。確保參數類型爲Object。還總是在您打算覆蓋的方法上添加@Override註釋。

2

我的印象是,當調用hashSet.add(n2)時,它調用Node.equals來查看n2的重複是否已經在set中,但是我錯了!

其實,你是正確的(有點)。

它調用boolean equals(Object)方法。但是你已經創建了一個超載的等於方法boolean equals(Node<T>) ...和該方法將不會方法調用HashSet方法。

寫equals方法是這樣的:

@Override 
boolean equals(Object node) { 
    ... 
} 

既然你已超負荷equals你還需要重載int hashcode() ...或者你的HashSet實例將打破。

+3

好的。值得注意的是,如果你認爲你的方法覆蓋了一個方法,用上面的StephenC顯示的@Override註解來註釋它。當你這樣做的時候,編譯器會警告你,如果你沒有真的重寫這個方法,而是重載它,就像你的問題一樣。 –

0

您應該重寫hashCode()方法。 如果不這樣做,jvm將自動爲每個對象生成hashCode,可能是將對象的內部地址轉換爲整數。

可以打印出N1和N2的hashCode,它們是不同的:

System.out.println(n1.hashCode()); 
System.out.println(n2.hashCode()); 
相關問題