Pergunta

I was working with StringBuilder to eliminate some unnecessary chars, I got some strange result.

String value = "1.045,00";
StringBuilder sanitized = new StringBuilder();
boolean decimalSeparatorFound = false;
char[] chars = value.toCharArray();
for (int i = chars.length-1; i >= 0; i--) {
    if (chars[i] == ',' || chars[i] == '.') {
        if (decimalSeparatorFound) continue;  // skip this char
        decimalSeparatorFound = true;
        sanitized.append('.');
    } else {
        sanitized.append(chars[i]);
    }
}

here I will get 00.5401 as a result in sanitized but when I was converting it to string like

String s = sanitized.reverse.toString();

and It is expected to print the value of s as 1045.00 but it get printed as 00.5401.

then I tried it as

StringBuilder sb = sanitized.reverse();
String s1 = sb.toString();

now this time it got printed correctly.

here my question why the StringBuilder is behaving this way? Isn't it performing reverse operation while assigning the value to String s?

Foi útil?

Solução

"my question why the StringBuilder is behaving this way?"

What's happening is that if you have both ways in the same code, it will reverse once, then reverse again

StringBuilder sb = sanitized.reverse();     // first reverse
String s1 = sb.toString();

String s = sanitized.reverse().toString();  // second reverse

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

OUTPUT

1045.00
00.5401

But if you take out the first reverse and just use the second reverse by itself, you get the correct output

String s = sanitized.reverse().toString();
System.out.println(s);

OUPUT

1045.00

Outras dicas

Change append to insert

            sanitized.insert(0, '.');
        } else {
            sanitized.insert(0, chars[i]);
        }

I would do it simpler

    String decimalSeparator = s.indexOf(',') > s.indexOf('.') ? "." : ",";
    s = s.replace(decimalSeparator, "");

In this loop, You are reversing the string by appending to StringBuilder from chars[chars.length-1] to chars[0]

for (int i = chars.length-1; i >= 0; i--) {
    if (chars[i] == ',' || chars[i] == '.') {
        if (decimalSeparatorFound) continue;  // skip this char
        decimalSeparatorFound = true;
        sanitized.append('.');
    } else {
        sanitized.append(chars[i]);
    }
}

This is the actual reason for the reversion. You should change the loop like this

for (int i = 0; i < chars.length; i++) {
        if (chars[i] == ',' || chars[i] == '.') {
            if (decimalSeparatorFound) continue;  // skip this char
            decimalSeparatorFound = true;
            sanitized.append('.');
        } else {
            sanitized.append(chars[i]);
        }
    }

So, it will work as you expect

Can you please try this:

Use StringBuilder's or StringBuffer's method... reverse()

public class StringReverse
{
  public static void main(String[] args)
  {
  String string=args[0];
  String reverse = new StringBuilder(string).reverse().toString();
  System.out.println("\nString before reverse: "+string);
  System.out.println("String after reverse: "+reverse);
  } 
}

StringBuffer is thread-safe, where as StringBuilder is Not thread safe.....

StringBuilder was introduced from Java 1.5, as to do those operations faster which doesn't have any Concurrency to worry about....

Hope this helps..

You didn't call reverse method in the right way. You should call it reverse() with braces.

Your line should be like this:

// now they will give you the same results
String s1 = sanitized.reverse().toString();
System.out.println(s1) //1045.00

StringBuilder sb = sanitized.reverse();
String s1 = sb.toString();
System.out.println(s1) //1045.00

Instead of doing this

for (int i = chars.length-1; i >= 0; i--) 

you should try this

for (int i = 0; i <chars.length; i++) 

May be you are using reverse two times.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top