2012-12-10 120 views
4

这个问题肯定不是一个新问题,但我没有在任何地方找到有用的答案。如你在下面的代码中看到的,equals和hashcode方法被覆盖,但它仍然允许重复。哈希码由Netbeans自动生成。Hashset允许重复?

@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,则它工作正常。如果在函数A之后执行函数B(所以上面的代码被执行了两次),那么即使system.err被触发说有重复项,哈希集合突然接受重复项?

代码中是否存在缺陷,或者我只是错过了一些东西?

感谢您的帮助!

+0

我怀疑某些操作newTaskDetails由于其中的哈希值正在改变。 – kosa

+0

你是否在重写这些方法? –

+1

你的意思是“接受重复”吗?整个对象是一样的,还是你的意思是重复ID? – Zutty

回答

7

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

+0

谢谢jtahlborn和Jochen!它似乎现在工作!这可能是为什么某些对象的哈希码相同。 – Xaviraan

0

这是一个重复的问题,请参阅我的previous answer

java.util.HashSet中的对象的哈希码可以更改时,会导致java.util.HashSet允许重复的行为。

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

3

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

0

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

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

请更正您的实施使用相同的属性。那么错误应该消失。

0

javadoc of Object

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合同不被打破。