public static void main(String[] args) {
HashSet set = new HashSet();
set.add(new StringBuffer(\"abc\"));
set.add(new StringBuffer(\"abc\"));
set.a
StringBuffer
doesn't override either equals
or hashCode
- so each object is only equal to itself.
This makes sense as StringBuffer
is very much "mutable by design" - and equality can cause problems when two mutable objects are equal to each other, as one can then change. Using mutable objects as keys in a map or part of a set can cause problems. If you mutate one after insertion into the collection, that invalidates the entry in the collection as the hash code is likely to change. For example, in a map you wouldn't even be able to look up the value with the same object as the key, as the first test is by hash code.
StringBuffer
(and StringBuilder
) are designed to be very transient objects - create them, append to them, convert them to strings, then you're done. Any time you find yourself adding them to collections, you need to take a step back and see whether it really makes sense. Just occasionally it might do, but usually only when the collection itself is shortlived.
You should consider this in your own code when overriding equals
and hashCode
- it's very rarely a good idea for equality to be based on any mutable aspect of an object; it makes the class harder to use correctly, and can easily lead to subtle bugs which can take a long time to debug.