Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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.

like image 566
Why So Serious Avatar asked Sep 01 '19 11:09

Why So Serious


3 Answers

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());
like image 146
Eran Avatar answered Nov 09 '22 23:11

Eran


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.

like image 2
yascho Avatar answered Nov 09 '22 22:11

yascho


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.

like image 2
Boann Avatar answered Nov 09 '22 23:11

Boann