簡體   English   中英

Hashset允許重復?

[英]Hashset allows duplicates?

這個問題肯定不是新問題,但我在任何地方都找不到任何有用的答案。

正如您在下面的代碼中看到的那樣,equals和hashcode方法被覆蓋,但它仍然允許重復。 Hashcode由Netbeans自動生成。

@Override
public boolean equals(Object o)
{
    TaskDetails other = (TaskDetails) o;
    if ( (id_subtask == other.id_subtask)
            && ((date.compareTo(other.date)) == 0) )
    {
        System.err.println("Duplicate Entry"+id_subtask+" + "+other.id_subtask);
        return true;
    }
    else
    {
        System.out.println("Good!" +id_subtask+" + "+other.id_subtask);
        return false;
    }

} 

@Override
public int hashCode() {
    int hash = 7;
    hash = 71 * hash + this.id_subtask;
    hash = 71 * hash + this.id_team_member;
    hash = 71 * hash + Float.floatToIntBits(this.nb_hours);
    hash = 71 * hash + (this.date != null ? this.date.hashCode() : 0);
    hash = 71 * hash + (this.comment != null ? this.comment.hashCode() : 0);
    hash = 71 * hash + (this.subtask_name != null ? this.subtask_name.hashCode() : 0);
    System.out.println("Hash : "+hash + "Subtask : " + id_subtask);
    return hash;       
}

這個代碼用於在hashset中添加一個條目:

TaskDetails newTaskDetails = new TaskDetails
                                (
                                    s.getId_subtask(),
                                    mus.teamMember.getId_team_member(),
                                    f,
                                    mysqlFormat.format(caldate),
                                    c.substring(0, Math.min(c.length(), 100)),
                                    s.getName_subtask()
                                );

                            allTasks.add(newTaskDetails);

(allTask​​s是Hashset)

此代碼用於函數A和B.

如果只執行功能A,它可以正常工作。 如果函數B在函數A之后執行(所以上面的代碼執行兩次),那么即使觸發了system.err說有重復的條目,hashset突然接受重復項?

代碼中是否存在缺陷,或者我只是遺漏了什么?

謝謝您的幫助!

您使用2個字段將2個對象視為“相等”,但您使用的字段數超過2個來構造哈希碼。 你的hashCode()方法不能比你的equals()方法更具體。 作為一個好的經驗法則,你的hashCode()方法不應該使用你的equals()方法不使用的任何字段(但是它可以使用更少的字段)。 更具技術性,如果2個對象“相等”,它們必須具有相同的哈希碼(反之則不需要)。

您違反了hashCode()和equals()之間的一致性要求。 如果兩個對象根據equals()相等,則它們也必須具有相同的散列。 因為您的equals只考慮兩個字段,而hashCode考慮更多,所以不滿足此要求。

這是一個重復的問題,請參閱我之前的回答

其中行為java.util.HashSet允許重復時當在對象的哈希碼引起java.util.HashSet可以改變。

當從可變字段構造對象的哈希碼時,通常會發生這種情況。

您的問題是執行hashCode()不匹配equals() 兩種方法都必須使用對象的相同屬性。

在你的實現中,即使equals()計算結果為truehashCode()也是不同的。 在這種情況下(不同的hashCode ), HashMap的對象是不同的。

請更正您的實現以使用相同的屬性。 然后錯誤應該消失。

來自Objectjavadoc

If two objects are equal according to the equals(Object) method, then
calling the hashCode method on each of the two objects must produce the
same integer result. 

對於根據equals(Object)方法相同的兩個對象,您的哈希碼是不同的,因此其他代碼HashSet將做出錯誤的假設,並返回錯誤的結果。

某些代碼的編寫方式依賴於其他符合“合同”的對象。 您的類不遵守Object合約,因此集合中的任何內容都不能被認為是有效的,因為集合要求Object不會被破壞。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM