繁体   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