Java:Set.contains()给出了错误的结果

时间:2016-05-04 20:01:15

标签: java contains

由于Set.contains(Object o)应该只使用equals来检查对象是否在Set中,以下两种方法如何产生不同的结果?在我的项目中,方法1不会抛出异常,但方法2会抛出异常。

有关信息,对象" group"在集合"组"中,因此方法1的工作方式与我期望的一样。

  

boolean java.util.Set.contains(Object o)

     
    

如果此set包含指定的元素,则返回true。更正式地,当且仅当此集合包含元素e时才返回true(o == null?e == null:o.equals(e))。

  

方法1:

boolean ex = true;
for (AccessControlGroup acg : groups) {
  if ((acg.equals(group))) {
    ex = false;
  }
}
if (ex) {
  throw new IllegalStateException("Invalid group");
}

方法2:

if (!(groups.contains(group))) {
  throw new IllegalStateException("Invalid group");
}

更多信息: 使用HashSet。

AccessControlGroup:

public List<AccessControlGroup> getInherits() {

    if (this.inherits == null) {
      this.inherits = new ArrayList<>();
    }
    return this.inherits;
}

public void setInherits(List<AccessControlGroup> inherits) {

    this.inherits = inherits;
}

public List<AccessControlPermission> getPermissions() {

    if (this.permissions == null) {
      this.permissions = new ArrayList<>();
    }
    return this.permissions;
}

public void setPermissions(List<AccessControlPermission> permissions) {

    this.permissions = permissions;
}

@Override 
public int hashCode() {

    final int prime = 31;
    int result = super.hashCode();
    // prevent infinity loops or other sick effects
    // result = prime * result + ((this.inherits == null) ? 0 : this.inherits.hashCode());
    result = prime * result + ((this.permissions == null) ? 0 : this.permissions.hashCode());
    result = prime * result + ((this.type == null) ? 0 : this.type.hashCode());
    return result;
}

@Override
public boolean equals(Object obj) {

    if (this == obj) {
      return true;
    }
    if (!super.equals(obj)) {
      return false;
    }
    if (getClass() != obj.getClass()) {
      return false;
    }
    AccessControlGroup other = (AccessControlGroup) obj;
    // prevent infinity loops or other sick effects...
    // if (!Objects.equal(this.inherits, other.inherits)) {
    // return false;
    // }
    if (!Objects.equals(this.permissions, other.permissions)) {
      return false;
    }
    if (!Objects.equals(this.type, other.type)) {
      return false;
    }
    return true;
    }

AccessControl的:

@Override
public int hashCode() {

    final int prime = 31;
    int result = 1;
    result = prime * result + ((this.id == null) ? 0 : this.id.hashCode());
    return result;
}

@Override
public boolean equals(Object obj) {

    if (this == obj) {
      return true;
    }
    if (obj == null) {
      return false;
    }
    if (getClass() != obj.getClass()) {
      return false;
    }
    AccessControl other = (AccessControl) obj;
    if (!Objects.equals(this.id, other.id)) {
      return false;
    }
    return true;
}

1 个答案:

答案 0 :(得分:0)

我在将group添加到集合groups后修改groups的可能性。这会改变它的hashCode,这会将它留在contains中的错误桶中,这意味着Set< AccessControlGroups > groups = new HashSet<>(); AccessControlGroup group = new AccessControlGroup(); groups.add( group ); groups.contains( group ); // true group.setPermissions( new ArrayList<>() ); groups.contains( group ); // false 将不会再找到它,除非新的hashCode碰巧与旧的hashCode冲突。

{ "_id" : "HsM4HpwrYAXh2PJeN",
  "contact" : [ {
    "emailAddress" : "harry@potter.com",
    "someContact" : "No",
    "creationDate" : "N/A",
    "hardBounceBack" : "N/A",
    "unsubscribed" : "No"
  } ]
}