Question

Whenever I use equals() method with two different StringBuffer objects, I get the result as false, but when I use equals() method with two different String objects, I get the result as true. Why?

    String s=new String("434");
    String s1=new String("434");

    System.out.println(s.equals(s1));//true

   StringBuffer s=new StringBuffer("434");
   StringBuffer s1=new StringBuffer("434");

   System.out.println(s.equals(s1));//false
Was it helpful?

Solution

StringBuffer does not override equals(). As such, Object.equals() is called, which compare the object identity (the memory address). String does override equals and compare the content.

OTHER TIPS

StringBuffer does not override Object#equals(), so you're experiencing reference identity-based checks rather than value-based checks. As these StringBuilder instances are distinct, each with different memory locations, the base Object#equals() implementation will always return false.

Here's the definition as of Java 6:

public boolean equals(Object obj) {
  return (this == obj);
}

See the problem?

At least in my version of the JDK (Sun 1.6), StringBuffer does not implement an equals() method. This means it inherits Object's equals() method, which is the same as ==

If you really want to test two StringBuffers for equality, you could call x.toString().equals(y.toString())

If what you are looking to do is compare the String representations of the two StringBuffer objects, then what you want to do is:

StringBuffer sb1 = new StringBuffer("434");
StringBuffer sb2 = new StringBuffer("434");
if (sb1.toString().equals(sb2.toString())) {
  // whatever you want to do if they're equal
} else {
  // whatever you want to do if they're not
}

Otherwise, you're comparing for equality of the two StringBuffer objects, not their contents -- in other words, executing Object#equals(), not (the non-existent) StringBuffer#equals().

equals only returns true on StringBuffer objects when the two objects are the same. To compare StringBuffers the way you want, use this:

System.out.println(s.toString().equals(s1.toString());

String s.equals will use the string table to compare the actual strings where as the StringBuffer sb.equals will just use the default implementation of the equals method and just compare the object pointers.

StringBuffer doesn't have it's own implemention of equals method it inherits the equals() method from the object class hence the hashvalues are compared rather than comparing the actual content in the stringBuffer. Hence we have to explicitly cast it to a string object which provides the implementation for equals() method.

The semantics of the String object are such that if two instances are ever observed to contain the same sequence of characters, they will always contain the same sequence of characters and one could--at least from the standpoint of the String object itself--replace all references to one of the strings with references to the other without changing program semantics. Such instances may be considered equivalent, because for all practical purpose, the only information encapsulated in an instance of String is the sequence of characters contained in the target instance.

By contrast, a variable of type StringBuffer encapsulates not just a sequence of characters, but also the identity of a particular instance. If two variables refer to the same instance, changing to the instance referred to by one variable will affect the instance referred to by the other (since it's the same instance). If they refer to different instances, changes to the instance referred to by one will not affect the instance referred to by the other. The decision not to have Java's StringBuffer override equals wasn't a result of laziness, but was rather based upon the fact that StringBuffer objects have a meaningful identity, and disjoint instances always have different identities.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top