chandu_reddim
chandu_reddim

Reputation: 117

StringBuilder implements Comparable but does not override equals

I don't understand this line from javadoc (under the subheading "API note"):

StringBuilder implements Comparable but does not override equals. Thus, the natural ordering of StringBuilder is inconsistent with equals.

I am a beginner in Java so could you explain this in a simple way?

Upvotes: 4

Views: 358

Answers (1)

BahmanM
BahmanM

Reputation: 1445

That means StringBuilder.compareTo() and StringBuilder.equals() don't always agree.

var sb1 = new StringBuilder("foo");
var sb2 = new StringBuilder("foo");
assert sb1.compareTo(sb2) == 0;      // as you would expect.
assert sb1.equals(sb2) == true;      // surprise - it fails

Now it gets a bit more confusing:

var map = new HashMap<StringBuilder, String>();
map.put(sb1, "lorem ipsum");
assert map.size() == 1;
map.put(sb2, "dolor sit amet");
assert map.size() == 1;            // fails - it's 2

var set = new TreeSet<StringBuilder>();
set.add(sb1);
assert set.size() == 1;
set.add(sb2);
assert set.size() == 2;           // you'd think this should be 2 but it fails! 

That's because HashMap works with equals() whereas SortedSet with compareTo().


NOTE 1: on equals()

StringBuilder extends Object, which means it inherits Object.equals(); but it does not override equals(), which means StringBuilder.equals() is actually Object.equals().

Object.equals() in turn is basically ==, ie it returns true if and only if the two objects are the same memory address.

Object.equals() java doc


NOTE 2: why?

Only starting from JDK11, StringBuilder implements Comparable. Any accompanying change in equals() could have caused some older client code to break; so, I'd think, following the Java tradition of keeping things backward compatible they dropped the idea.

Upvotes: 8

Related Questions