2

p.equals(w) is always coming true. Why ?

http://ideone.com/JqLCDi

 import java.io.*; import java.util.Scanner; class TestClass { public static void main(String args[] ) throws Exception { Scanner s=new Scanner(System.in); int t=s.nextInt(); while(t-->0){ String k=s.next(); StringBuffer p=new StringBuffer(k); int c=0; StringBuffer w=p.reverse(); if(p.equals(w)){ System.out.print(p.equals(w)); for(int i=0;i<p.length();i++) { if(p.charAt(i)=='1'||p.charAt(i)=='0'||p.charAt(i)=='8') { c++;} } } if(c==p.length())System.out.println("YES"); else System.out.println("NO"); } } } 
2
  • Why don't you use equalsIgnoreCase() ? Commented Jun 19, 2014 at 17:37
  • Even a correctly copied (!) and reversed buffer will always compare not equal because StringBuffer does not override equals. Commented Jun 19, 2014 at 17:39

3 Answers 3

4
public synchronized StringBuffer reverse() { super.reverse(); return this; } 

Reverse will reverse the String and set it in the same StringBuffer object. So it will always be the same.

So

p.reverse(); 

does the same thing as saying

p = p.reverse(); 

And then if you do

StringBuffer w=p.reverse(); 

p and w will pint to same object. Needless to say equals() will return true.

You can store String Objects before and after reverse operation on StringBuffer and then use equals() on them. toString() returns new String Object.

public synchronized String toString() { return new String(value, 0, count); } 
Sign up to request clarification or add additional context in comments.

2 Comments

Good catch. +1 Now you just need the solution.. :)
Yeah was just typing the solution :)
2

Unlike String, StringBuffer1 is a mutable type. True to this design, StringBuffer.reverse modifies the original object and then returns the same (current) StringBuffer instance; returning the same instance allows for method-chaining:

[reverse] causes this character sequence to be replaced by the reverse of the sequence [and returns] a reference to this [StringBuffer] object.

Thus

StringBuffer w=p.reverse(); 

is semantically equivalent to

p.reverse(); // side-effect! reverses content StringBuffer w == p; // w == p -> true (same object), implies w.equals(p) -> true 

One approach to solve this is to create a new StringBuffer instance for w, and reverse after.

StringBuffer w = new StringBuffer(p); // w == p -> false, w.equals(p) -> true p.reverse(); // w == p -> false, w.equals(p) -> false 

If only needing a String, the same rules/logic apply - create a new object/copy of the data before reversing the StringBuffer.

String s = p.toString() // s == p -> false, s.equals(p) -> true p.reverse(); // s == p -> false, s.equals(p) -> false 

While I doubt this is the actual task, consider p.toString.equals(p.reverse()) which also follows the preceding logic.

boolean reversed = p.toString() // "s", new String / data copy .equals( p.reverse() // "p", reverse done after copy ); 

1 StringBuffer is old, use StringBuilder going forward unless the synchronization properties are required:

[StringBuilder] is designed for use as a drop-in replacement for StringBuffer in places where the string buffer was being used by a single threaded.. Where possible, it is recommended that this class be used in preference to StringBuffer as it will be faster under most implementations.

2 Comments

Even easier: just use String current = p.toString(); String reversedContent = p.reverse().toString(); /* compare current against reversedContent */.
@LuiggiMendoza Thanks, I've included the case of using toString as opposed to creating a new SB.
1

Use this in your if condition

if(p.toString().equals(p.reverse().toString())) 

1 Comment

This doesn't work if you use StringBuffer#reverse because they both will have the same content...

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.