Home > database >  Java: set.remove() method doesn't remove the object from Set
Java: set.remove() method doesn't remove the object from Set

Time:09-29

I am making a small mistake I think while trying to remove an object from the set in the forEach() loop. The remove() doesn't remove the object, can anyone point out what the issue could be? Thanks!

Set<RoleExtEntity> roleExtEntitySet = roleEntity.getExt(); //set size = 3
Map<String, RoleExtEntity> roleExtEntityMap = 
        new HashMap<>(roleExtEntitySet.size());

roleExtEntitySet.stream().forEach(roleExtEntity -> {
      if (role.getName() == null && roleExtEntity.getKey().equals("name")) {
            //this line doesn't work; set size should be 2 but it's still 3
            roleExtEntitySet.remove(roleExtEntity);
      } else {
            roleExtEntityMap.put(roleExtEntity.getKey(), roleExtEntity);
      }
});

CodePudding user response:

can anyone point out what the issue could be

Without seeing your code, I'd guess that it's because you're not overriding equals and/or hashCode correctly, and/or you have modified roleExtEntity since it was put into the map in a way that affected the hashCode.

Irrespective, if this remove actually did work, you would risk a ConcurrentModificationException, because you are removing from the collection you are iterating.

You can instead do this with an explicit Iterator, which allows you to remove():

for (Iterator<RoleExtEntity> it = roleExtEntitySet.iterator(); it.hasNext();) {
  RoleExtEntity roleExtEntity = it.next();
  if (...) {
    it.remove();
  } else {
    // ...
  }
}

An alternative could be to split up the forEach into something doing the removing, and something doing the putting:

if (role.getName() == null) { // Since role appears to be unchanged in the loop
  roleExtEntitySet.removeIf(roleExtEntity -> roleExtEntity.getKey().equals("name"));
}

Map<String, RoleExtEntity> roleExtEntityMap =
    roleExtEntitySet.stream().collect(
        Collectors.toMap(RoleExtEntity::getKey, r -> r));
  • Related