While working with a tree set, I found very peculiar behavior.
As per my understanding following program should print two identical lines:
public class T
Well, this surprised me, I don't know if I'm correct, but look at this implementation in AbstractSet
:
public boolean removeAll(Collection> c) {
Objects.requireNonNull(c);
boolean modified = false;
if (size() > c.size()) {
for (Iterator> i = c.iterator(); i.hasNext(); )
modified |= remove(i.next());
} else {
for (Iterator> i = iterator(); i.hasNext(); ) {
if (c.contains(i.next())) {
i.remove();
modified = true;
}
}
}
return modified;
}
Basically in your example, the size of set is equal to the size of arguments you want to remove, so the else condition is invoked. In that condition there is a check if your collection of arguments to remove contains
the current element of iterator, and that check is case sensitive, so it checks if c.contains("a")
and it returns false, because c
contains "A"
, not "a"
, so the element is not removed. Notice that when you add an element to your set s.addAll(Arrays.asList("a", "b", "d"));
it works correctly, because size() > c.size()
is now true, thus there is no contains
check anymore.