Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java += operator on String with charAt() methods results in char addition

I'm working through the problems on Codingbat.com and bumped into the fact that for the += operator, a += b isn't necessarily exactly equal to a = a + b. This is well known and has been discussed on SO before, but I bumped into something strange happening when using the charAt() method combined with the above syntax that I can't make sense of.

Say I have two variables:

String str    = "The";
String result = "";

I want to add the first letter in "str" two times to "result". One way of doing this is to:

result = result + str.charAt(0) + str.charAt(0);

which results in result = "TT".

However, if I use the += operator, e.g.:

result += str.charAt(0) + str.charAt(0);

I get result = "168". Clearly character addition has taken place (ASCII code for 'T' is 84, 84*2 = 168).

I'm wondering what is actually going on in the first case using the += operator. According to the docs on assignment operators: E1 op= E2 is equivalent to E1 = (T)((E1) op (E2)). So I would expect the latter expression to output "168" just like using the += operator did. But the following outputs "TT" correctly, and not "168":

result = (String)(result + str.charAt(0) + str.charAt(0));

Have I just misunderstood the documentation? I also found an answer on SO that suggests that str1 += str2 is equivalent to:

str1 = new StringBuilder().append(str1).append(str2).toString();

But evaluating the following:

result = new StringBuilder().append(str.charAt(0)).append(str.charAt(0)).toString();

Still results in "TT", not "168".

Sorry for the long post! I'm just curious at what actually is happening when using charAt() in combination with a String and +=, because the two "equivalents" I've found (if I've translated them from two to three terms correctly) does not produce the same result.

like image 659
jodles Avatar asked Jul 24 '14 15:07

jodles


3 Answers

result = result + str.charAt(0) + str.charAt(0);

result is a string, so the first + performs string concatenation, producing another string. The second +, by the same logic, will also perform string concatenation. This gives the desired result.

result += str.charAt(0) + str.charAt(0);

The right-hand side, str.charAt(0) + str.charAt(0), is evaluated first. Now, you're adding two characters, which works like simple integer addition, adding the ASCII values. We then append this result (an int -- 84 in this case) to result, which is what you see.

char c = 'T';
System.out.println(c + c);
168

The underlying difference here is just the order in which things are evaluated.

like image 122
arshajii Avatar answered Nov 12 '22 22:11

arshajii


As you stated in your question E1 op= E2 is equivalent to E1 = (T)((E1) op (E2)). So the line

result += str.charAt(0) + str.charAt(0);

is equivalent to

result = (String) ((result) + (str.charAt(0) + str.charAt(0)));

(Note the parentheses around the char addition, they are important)

This will evaluate to

result = (String) (("") + ('T' + 'T'));
result = (String) (("") + (168));
result = (String) ("168");
result = "168";

whereas without parentheses you get

result = (String) ("" + 'T' + 'T');
result = (String) ("T" + 'T');
result = (String) ("TT");
result = "TT";
like image 31
SamYonnou Avatar answered Nov 12 '22 23:11

SamYonnou


str.charAt(0) + str.charAt(0)

is evaluated as a whole before the assignment += takes place.

charAt returns a char, on which addition is defined like on integers. Therefore, this is the same as :

result = result + (str.charAt(0) + str.charAt(0));
like image 38
njzk2 Avatar answered Nov 12 '22 22:11

njzk2