5

这个问题肯定不是一个新问题,但我在任何地方都没有找到任何有用的答案。

正如您在下面的代码中看到的,equals 和 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 被触发说有重复条目?

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

谢谢您的帮助!

4

5 回答 5

8

您正在使用 2 个字段将 2 个对象视为“相等”,但您正在使用超过 2 个字段来构造哈希码。你的hashCode()方法不能比你的equals()方法更具体。作为一个好的经验法则,您的hashCode()方法不应该使用您的方法不使用的任何字段equals()(但是它可以使用更少)。更专业地说,如果 2 个对象“相等”,它们必须具有相同的哈希码(不需要相反)。

于 2012-12-10T15:31:21.090 回答
3

您违反了 hashCode() 和 equals() 之间的一致性要求。如果两个对象根据 equals() 相等,则它们也必须具有相同的哈希值。因为你的 equals 只考虑两个字段,而 hashCode 考虑的更多,所以不满足这个要求。

于 2012-12-10T15:33:31.787 回答
0

这是一个重复的问题,请参阅我之前的回答

ajava.util.HashSet允许重复的行为是在java.util.HashSetcan 中对象的哈希码发生变化时引起的。

这通常发生在从可变字段构造对象的哈希码时。

于 2012-12-10T15:33:04.287 回答
0

你的问题是执行hashCode()不匹配equals()。两种方法都必须使用对象的相同属性。

hashCode()即使equals()评估为,在您的实现中也可能有所不同true。在这种情况下(不同hashCode的 s),对象对于 是不同的HashMap

请更正您的实现以使用相同的属性。然后错误应该消失。

于 2012-12-10T15:33:35.103 回答
0

来自javadocObject

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不违反合同。

于 2012-12-10T15:34:14.610 回答