当set包含元素时,java set.contains()给出false?

时间:2014-02-27 21:55:45

标签: java set equality

请参阅下面的junit测试代码段。帐户有一个带有分配的集合。当包含的城市名称等于'Bladel'

时,我想从赋值中删除一个元素
Assignment toBeDeleted = null;
for (Assignment ass : account.getAssignments()) {
    if (ass.getCity().getName().equals("Bladel")) {
        toBeDeleted = ass;
        break;
    }
}
Assert.assertNotNull(toBeDeleted);
for (Assignment ass : account.getAssignments()) {
    logger.info(String.format("hash [%s] %d with [%s] %d",toBeDeleted.getCity().getName(), toBeDeleted.hashCode(), ass.getCity().getName(), ass.hashCode()));
    if (ass.equals(toBeDeleted)) {logger.info("found equal assignment"); }
    if (ass.hashCode() == toBeDeleted.hashCode()) {logger.info("found equal hash assignment"); }
    if (ass == toBeDeleted) { logger.info("it is == with"); }
}
Assert.assertTrue(account.getAssignments().contains(toBeDeleted));

但是失败了所以我用.remove() Stil取代.contains()失败了。该日志明确显示toBeDeleted在某个时刻等于集合中的元素:

2014-02-27 22:33:35 INFO  AssignmentDAOTest:134 - found equal assignment
2014-02-27 22:33:35 INFO  Assignment:66 - for assignment + Bladel result is 2121952
2014-02-27 22:33:35 INFO  Assignment:66 - for assignment + Bladel result is 2121952
2014-02-27 22:33:35 INFO  AssignmentDAOTest:135 - found equal hash assignment
2014-02-27 22:33:35 INFO  AssignmentDAOTest:136 - it is == with

出了什么问题?当remove()返回true时,我认为contains()equals()匹配。

每条评论: Account是Hibernate映射的java类,集合的总体是在单元测试中留给Hibernate。

public class Account {
    ....
@OneToMany(mappedBy="account", fetch=FetchType.LAZY, cascade={CascadeType.ALL})
public Set<Assignment> getAssignments() {return assignments;}
public void setAssignments(Set<Assignment> asgmnts) {
    logger.info("setting assignments");
    assignments = asgmnts;
}

1 个答案:

答案 0 :(得分:1)

如果您使用TreeSet存储分配,则需要覆盖Assignment类中的compareTo()方法,或者提供自定义比较器以比较Assignment对象。

以下是来自javadoc的文字:link

  

请注意,如果要正确实现Set接口,则由set维护的排序(无论是否提供显式比较器)必须与equals一致。 (有关与equals一致的精确定义,请参阅Comparable或Comparator。)这是因为Set接口是根据equals操作定义的,但TreeSet实例使用compareTo(或compare)方法执行所有元素比较,因此从集合的角度来看,通过这种方法被认为相等的元素是相等的。集合的行为即使其排序与equals不一致也是明确定义的;它只是没有遵守Set接口的一般合同。