Granny's Programming Pearls
"inside of every large program is a small program struggling to get out"
JavaRanch.com/granny.jsp
Win a copy of Kotlin in Action this week in the Kotlin forum!
  • Post Reply Bookmark Topic Watch Topic
  • New Topic

Why StringBuilder doesn't override equals()  RSS feed

 
Fred Kleinschmidt
Bartender
Posts: 560
9
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I don't understand why StringBuilder's .equals method is the same as the ineffectual == operator; why didn't they make it actually evaluate the objects rather than forcing us to write an override? 

First of all, the == operator is NOT ineffectual; it does exactly what it should do - it determines whether two variables reference the same StringBuilder.
Second, you don't have to create an override to compare the string content of two StringBuilders:

 
Julian West
Ranch Hand
Posts: 91
3
Chrome Java Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Clarifying my question: Why didn't they override Object's equals method with StringBuilder's own equals method that actually compares the content rather than the object references that we already have with ==?

As SB stands now, I have to write my own equals method or use .toString() to do what is common: compare strings, which seems to go against the "code re-use" philosophy.  Or am I missing something? (which I'm defaulting to the latter...so what am I missing?)

 
Julian West
Ranch Hand
Posts: 91
3
Chrome Java Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
hehe we posted at the same time.

I meant ineffectual at comparing two strings, which is would I would assume would be more predominantly done with Strings and StringBuilder objects.  I can understand keeping == consistent across all object references but what I do not understand is that we can use .equals with String but not with the 'improved' StringBuilder--what was the design behind that decision that I am missing? 
 
Campbell Ritchie
Marshal
Posts: 55717
163
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Julian West wrote:. . . why StringBuilder's .equals method is the same as the ineffectual == operator . . .
That merits a thread of its own, so I might separate this post into a new thread. Original question was here.
There is nothing ineffectual about ==; when applied to reference types it tells you whether what is on its left and what is on its right is the same object. Most of the time that returns false, so you use the equals() method instead. The use of == on reference types should be avoided except for a few exceptions. The exceptions include:-
  • 1: When either operand is the null literal.
  • 2: When you are using true singletons, which nowadays shou‍ld always mean enum constants.
  • 3: When you are writing an equals method.
  • More details here. The equals method in the Object class uses == internally because there are no fields in Object which can sensibly be compared. The == operator is the strictest test which fulfils the requirements of the equals method, viz. that every object is equal to itself. It is recommended that you override the equals method, but there are some classes which you write where you know you aren't going to use equals, so you can get away without overriding it. In the standard API, there are classes which don't override equals because:-
  • 1: Each instance is implicitly different from all other instances, e.g. Thread, Class<T>, Stream<T>
  • 2: The classes are singletons, which is rather similar to the above case: all instances are different from each other. All enums come into this category.
  • 3: The state of the object will change rapidly: StringBuilder falls in this category because it is intended for local use and changes frequently.
  • 4: It uses an overridden method from a superclass. ArrayList is an example.
  • You can find out by looking in the API documentation and seeing whether equals appears in the method summary or under methods inherited from XXX.

    If you need to find out whether two StringBuilders have the same contents use
    myFirstStringBuilder.toString().equals(mySecondStringBuilder.toString())
     
    Campbell Ritchie
    Marshal
    Posts: 55717
    163
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Fred Kleinschmidt wrote:. . . you don't have to create an override to compare the string content of two StringBuilders:

    Aaaaaaaaaaaaaaaaaaaargh! You beat me to it.

    Actually, you cannot create an override, because the StringBuilder class cannot be extended (it is final).
     
    Dave Tolls
    Rancher
    Posts: 2914
    36
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    As for why it doesn't override equals I would argue that it is not the purpose of the class.
    It's job is to build up a String that you will use later on, so comparison doesn't make much sense.

    If you find yourself doing sb.toString().equals(anotherSB.toString()) then it's quite likely you are doing something a little wrong.  Not always, as I expect someone has a use for it, but I have never seen one.
     
    Campbell Ritchie
    Marshal
    Posts: 55717
    163
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    I have used that kludge once when trying to build two Strings in parallel in the same method, but I cannot remember whether that was really necessary. It sounds like the sort of convoluted code you write when you are beginning. You are right. Build the Strings and you can compare them when you have finished with the builders.
     
    Stephan van Hulst
    Saloon Keeper
    Posts: 7808
    142
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    There is an important difference between types that represent data, and types that 'do something'.

    For instance, a List is a data type. You can use the equals() method to compare the two lists for their content.

    A StringBuilder is a 'do type'. Even if the contents of two instances may be the same, they may be used in different ways to create two different end results. One could argue the same is true for a List, but lists represent data now. Builders represent data in the future.
     
    Campbell Ritchie
    Marshal
    Posts: 55717
    163
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Useful classification of types thank you.
     
    It is sorta covered in the JavaRanch Style Guide.
    • Post Reply Bookmark Topic Watch Topic
    • New Topic
    Boost this thread!