Why is this reversed StringBuilder not equal to the original String, when it is a palindrome?
Asked Answered
W

3

6

I was trying to check that a String is a palindrome using StringBuilder and reverse(). For a word with no symmetry like "chan" it correctly returns false, but it also returns false for genuine palindromes like "madam".

Code:

StringBuilder str = new StringBuilder("madam");
StringBuilder str2 = new StringBuilder(str);
boolean res = str2.equals(str.reverse().toString().trim());
System.out.println(str + " " + str2);
System.out.println(res);

Output:

madam madam
false

I am running Eclipse Neon with Java 8.

Whitehurst answered 1/9, 2019 at 11:11 Comment(4)
Use a debugger to find it out.Hessite
You compare a String with a StringBuilder.Hessite
why do you need to trim the result?Bravissimo
even not working after rermoving trim()Whitehurst
B
10

str.reverse().toString().trim() is a String, so it cannot be equal to a StringBuilder.

Try to compare 2 Strings instead:

boolean res=str2.toString().equals(str.reverse().toString().trim());
Bedridden answered 1/9, 2019 at 11:13 Comment(0)
S
2

If you want to compare strings, you need to use str2.toString():

boolean res=str2.toString().equals(str.reverse().toString().trim());

Full solution:

StringBuilder str=new StringBuilder("madam");
StringBuilder str2=new StringBuilder(str);
boolean res=str2.toString().equals(str.reverse().toString().trim());
System.out.println(str+" "+str2);
System.out.println(res);

Output:

 madam madam true

The problem is that you are comparing a StringBuilder object str2 with a String, instead of comparing the two Strings. Furthermore, trim() is not needed as your String contains only letters.

Salesman answered 1/9, 2019 at 11:12 Comment(0)
I
2

This line is comparing str2, an instance of StringBuilder, with an instance of String:

boolean res = str2.equals(str.reverse().toString().trim());

It's common for objects of two different classes to always say they are not equal, because they aren't generally programmed to know how to examine the contents of different types of object. (There are some cases where it's specified to work, such as different implementations of java.util.List.)

In this case, it's even worse, because StringBuilder does not override the equals method at all. If you check the class documentation, you'll see equals listed as one of the methods inherited from Object. So it will return true only when passed the same object instance; it never compares content.

StringBuilder sb1 = new StringBuilder("abc");
StringBuilder sb2 = new StringBuilder(sb1);
System.out.println(sb1.equals(sb1)); // true; same object
System.out.println(sb1.equals(sb2)); // false; different objects (same content)

So you cannot compare any StringBuilder instances this way. To do the comparison, convert your reversed result back to a plain String:

String input = "madam";
input = input.trim();
String reversed = new StringBuilder(input).reverse().toString();
System.out.println(input + " " + reversed);
System.out.println(input.equals(reversed));

Note: If you want to trim() a user input, do it at the earliest moment. If you trim after reversal, you will have to trim both halves of the comparison.

Iphlgenia answered 1/9, 2019 at 13:34 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.