31

Why does StringBuffer/StringBuilder does not override the equals(), hashcode() methods from object?

Please suggest me clear picture that helps the understand the problem...

Saravanan
  • 11,372
  • 43
  • 143
  • 213

3 Answers3

42

Because StringBuffer is mutable, and its primary use is for constructing strings. If you want to compare content, call StringBuffer#toString() and compare the returned value.

It is not generally useful to override hashCode() for mutable objects, since modifying such an object that is used as a key in a HashMap could cause the stored value to be "lost."

Matt Ball
  • 354,903
  • 100
  • 647
  • 710
  • what does Mutable means here? – Saravanan Jun 20 '12 at 04:01
  • 6
    Do some research if you don't understand the very basic principles: http://stackoverflow.com/questions/3554192/what-is-a-mutable-class-in-oop – Matt Ball Jun 20 '12 at 04:02
  • 2
    With all due respect I disagree with your statement _It is not generally useful to override hashCode() for mutable objects..._ – Shahzeb Jun 20 '12 at 04:22
  • 1
    @Shahzeb how about an example of when a mutable object's `hashCode()` might be used? – Matt Ball Jun 20 '12 at 10:28
  • 1
    First obvious point of reference for me was any ORM class so here is a link from [hibernate](http://tinyurl.com/7qbd7fv) and a long discussion here at SO http://stackoverflow.com/questions/5031614/the-jpa-hashcode-equals-dilemma – Shahzeb Jun 20 '12 at 21:57
  • @MattBall sir can u please elaborate your answer with example of hashmap you are talking about in your answer. I am very close in getting your whole point but still i am confuse a little bit :( – Prince Vijay Pratap Mar 25 '18 at 14:19
  • @PrinceVijayPratap the short answer is that `String` is a far better key to use in a `Map` than `StringBuffer`/`StringBuilder`. – Matt Ball Mar 25 '18 at 16:00
  • @MattBall ok I get it why it is better key ty :) – Prince Vijay Pratap Mar 27 '18 at 12:58
8

Actually behind this everything depends upon the hashcode code value. To understand this concept let's take an example :

String str1 = new String("sunil");
String str2 = new String("sunil");

HashMap hm = new HashMap()
hm.put(str1,"hello");
hm.put(str2,"bye");

final hm:

hm = { sunil=bye }

In above code, str1 and str2 are two different String objects. Should they be added to the HashMap separately? The answer is NO. This is because before inserting/putting a value in HashMap, it internally checks and compares the hashCode values of str1, str2. Both return the same hashcode value because the String class overrides equals() and hashcode() methods. So upon executing hm.put(str2,"bye"); first key will get overriden with the new value. Now try this :

StringBuilder sb1 = new StringBuilder("sunil");
StringBuilder sb2 = new StringBuilder("sunil");

HashMap hm = new HashMap()
hm.put(sb1,"hello");//sb1 and sb2 will return different HashCode 
hm.put(sb2,"bye");// StringBuffer/StringBuilder does not override hashCode/equals methods

final hm:

{sunil=hello, sunil=bye}

Both value will be added in hashMap because sb1 and sb2 both returns different hashcode. StringBuilder/ StringBuffer does not override equals() and hashCode() method.

Sun Microsystem wanted the programmer to allow adding 2 different String kind of Values in Hashtable or any other Hash Collections likes (HashSet,HashMap…),that’s the reason hashCode() and equals() were not overridden intentionally in StringBuffer,StringBuilder class.

Ojasvi Monga
  • 4,437
  • 2
  • 18
  • 35
Sunil Sharma
  • 1,297
  • 3
  • 17
  • 31
  • 2
    `Sun Microsystem wanted the programmer to allow adding 2 different String kind of Values in Hashtable ...` That's not true, javadocs for [`Hashtable`](https://docs.oracle.com/javase/8/docs/api/java/util/Hashtable.html) and [`Map`](https://docs.oracle.com/javase/8/docs/api/java/util/Map.html) actively discourage using objects with a broken `equals/hashcode` contract as keys. Storing `StringBuilder` objects in a map isn't useful because you won't be able to get the value by the key unless you have your original object. – default locale Feb 01 '18 at 10:59
-1

Because StringBuffer is mutable. With example Try This:)

package test;

import java.util.HashMap;

public class CheckHashcodeEquals {

    public static void main(String[] args) {

        /*
         * String class override equals() and hashcode() method thats way
         * override value of HashMap
         */
        String s1 = new String("Arya");
        String s2 = new String("Arya");
        HashMap hm = new HashMap<>();
        hm.put(s1, "A1");
        hm.put(s2, "A2");
        System.out.println(hm); /* Output: {Arya=A2} */

        /*
         * String class does not override equals() and hashcode() method thats
         * way insert duplicate value
         */
        StringBuffer sb1 = new StringBuffer("Arya");
        StringBuffer sb2 = new StringBuffer("Arya");
        HashMap hm2 = new HashMap<>();
        hm2.put(sb1, "A1");
        hm2.put(sb2, "A2");
        System.out.println(hm2); /* Output: {Arya=A2, Arya=A1} */
    }

}
user207421
  • 305,947
  • 44
  • 307
  • 483
MAnoj Sarnaik
  • 1,592
  • 16
  • 16
  • This example demonstrates that `StringBuffer` doesn't override `equals` and `hashcode`, but doesn't show why. The answer itself (`Because StringBuffer is mutable`) is copied from an earlier answer. – default locale Feb 01 '18 at 10:33