Akshay Ravichandran
Akshay Ravichandran

Reputation: 31

Why am I getting true for a reversed string, which is not equal in Java?

public class Main
{
    public static void main(String[] args) {
        StringBuilder string = new StringBuilder("abb");
        StringBuilder stringReverse = string.reverse();
    
        if(string.toString().equals(stringReverse.toString())){
            System.out.println(true);
            return;
        }
    
        System.out.println(false);
    }
}

See this code run live at IdeOne.com.

I get the output of the above code as 'true'. But the reversed string is 'bba'. How is 'bba' equal to 'abb'? Please could someone help me with this?

Upvotes: 1

Views: 77

Answers (4)

Basil Bourque
Basil Bourque

Reputation: 338516

The first three Answers are correct. One of them should be accepted. I will add one small thought about the importance of naming.

Naming can confuse or clarify

This Question is an example of how poor naming can lead you astray.

Naming your first StringBuilder with the word string leads one to think of that var as referencing a mutable String object when in fact it references a mutable StringBuilder. Naming something like firstStringBuilder would avoid this problem of being easy to misread.

StringBuilder string = new StringBuilder("abb");
//            ^^^^^^ No, this is not an immutable `String` object reference.

Alternate naming clarifies.

StringBuilder firstStringBuilder = new StringBuilder( "abb" );
StringBuilder reversedStringBuilder = firstStringBuilder.reverse();  // Both vars ( `firstStringBuilder` & `reversedStringBuilder` ) reference the very same single `StringBuilder` object. 

if( firstStringBuilder.toString().equals( reversedStringBuilder.toString() ) ){
    System.out.println( "firstStringBuilder & reversedStringBuilder are equal because they both point to the very same single StringBuilder object. So the result of calling `.toString` twice on the same object is the same." );
    return;
}

System.out.println( "Not equal" );

See this code run live at IdeOne.com.

firstStringBuilder & reversedStringBuilder are equal because they both point to the very same single StringBuilder object. So the result of calling .toString twice on the same object is the same.

Upvotes: 0

Hovercraft Full Of Eels
Hovercraft Full Of Eels

Reputation: 285403

StringBuilder#reverse() reverses the text in the StringBuilder itself (and returns the same). Print out the values held by string and stringReverse to see for yourself:

System.out.println("string: " + string);
System.out.println("stringReverse: " + stringReverse);

returns

string: bba
stringReverse: bba

Even more importantly, the API for StringBuilder tells you this:

Causes this character sequence to be replaced by the reverse of the sequence.

Also, the string and stringReverse are one and the same object, in other words, this:

System.out.println("stringReverse  == string: " + (stringReverse == string));

will print out true

Upvotes: 3

Bohemian
Bohemian

Reputation: 425013

reverse() returns the same object (not a new StringBuilder).

Your code:

StringBuilder string = new StringBuilder("abb");
StringBuilder stringReverse = string.reverse();

is identical to:

StringBuilder string = new StringBuilder("abb");
string.reverse();
StringBuilder stringReverse = string; // Same object!

Upvotes: 2

Scary Wombat
Scary Wombat

Reputation: 44834

As StringBuilder is mutable, when you are calling reverse you are actually reversing the original StringBuilder.

Try

StringBuilder string = new StringBuilder("abb");
StringBuilder stringReverse = new StringBuilder(string).reverse();
     
System.out.println(string.toString());
System.out.println(stringReverse.toString());

Upvotes: 1

Related Questions