Java: Set.contains () дает неверный результат

С Момента Съемок.contains (Object o) должен просто использовать equals, чтобы проверить, находится ли объект в наборе, как следующие два метода могут дать разные результаты? В моем проекте метод 1 не создает исключение, но метод 2 создает исключение.

Для информации, объект » группа «находится в наборе» группы», поэтому метод 1 работает так, как я ожидал бы.

boolean java.util.Набор.содержит (объект o)

Возвращает true, если этот набор содержит указанный элемент. Более формально, возвращает true тогда и только тогда, когда этот набор содержит элемент e такой, что (o==null ? e= = null : o.равно (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 ответ

  1. Я ставлю на то, что вы изменили groupпосле добавления его в набор groups. Это изменит его хэш-код , который оставит его в неправильном ведреgroups, что будет означать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