Why does an Integer concatenated with a number result in a string? - java

I was going through an AP Comp Sci practice test and found the following problem:
what is the output of:
System.out.println("1" + new Integer(2) + 3);
The answer was
123,
I am confused as the new Integer(2) has not been casted into a String and therefore why does the java compiler believe that the new Integer(2) + 3 statement is a String concatenation if both parts are integers?

Addition is left associative. a + b + c == (a + b) + c

Is the answer as simple as order of operations meaning that the statement is evaluated left to right so it could read.
System.out.println("1" + new Integer(2).toString() + 3.toString());

First, as the guy points out, addition is left-associative.
Second, the overload resolution of "1" + 2 is controlled by the left operand, which is a String. That forces concatenation, and the result is "12".
Now, "12" + 3 goes through the exact same overload resolution, and you get "123".

The original question was:
System.out.println("1" + new Integer(2) + 3);
and why does that give us "123"; I assume the questioner meant rather than 6 or "15"?
Let's simplify this and remove the new Integer bit to its equivalent:
System.out.println("1" + 2 + 3);
The Java Language Specification 12 gives the answer (4.2.2):
The string concatenation operator + (§15.18.1), which, when given a String
operand and an integral operand, will convert the integral operand to a String
(the decimal form of a byte, short, int, or long operand, or the character
of a char operand), and then produce a newly created String that is the
concatenation of the two strings. https://docs.oracle.com/javase/specs/
The 15.18.1 section is even more clear:
The additive operators have the same precedence and are syntactically left-associative
(they group left-to-right).
If the type of either operand of a + operator is String, then the operation is string
concatenation. https://docs.oracle.com/javase/specs/
So, since the operator + is used in both cases, it evaluates left-to-right, whether it is concatenation or addition, as stated in 15.18.1 and as other answerers have stated. The first operand "1" is a string and the second an integer 2, so according to the above rule, the integer 2 is converted to a string "2" and the plus is interpreted as concatenation, giving us a string "12". Then it has a string "12" and an integer 3, so the integer 3 is converted according to the above rule and the + is again interpreted as concatenation and we get a string "123".
If they had put parentheses around the 2 + 3:
System.out.println("1" + (2 + 3));
That, obviously, would force the 2 + 3 to be evaluated first. They are both integers, so you get an integer 5. Then we would have "1" + 5, which is a string plus an integer, so the integer is converted to a string "5" and they are concatenated, yielding "15".
If they had changed the order like this:
System.out.println(2 + 3 + "1");
Then, the 2 + 3 would be done first in accordance with the left-to-right rule, and since they are both integers, + would mean addition and that would yield an integer 5. Then we would have operators integer 5 and a string "1". According to the above rule, the integer 5 is converted to a string 5 and the + is interpreted as concatenation and we get a string "51".
So this all boils down to order of operations, the fact that all of these operations are really binary (you only take two at a time), and, when using a plus sign, if one operand is a string, the other is changed to a string if it is not already one, the plus sign is interpreted as concatenation, and the result is a string.

Related

Can someone please help me with this Java manipulation code. I wanna know how come the last two printouts are 35 respectively instead of 8? [duplicate]

I am trying to understand how the compiler views the following print statements. It is simple yet a bit intriguing.
This prints the added value. Convincing enough.
System.out.println(1+2); //output: 3
The output from the following looks convincing as well:
System.out.println(1+2+"3");//output: 33
My question (based on the behavior above) is here.
System.out.println("1"+2+3);//Should be 15 right? NO. It is 123.
I tried few other such statements which were along the same lines. I was able to see one two clear behaviors.
If integers are at the front, without the quotes, they are added and subsequent integers are just appended as suffix to the added values from the front.
if the statement starts with string, under quotes, then all other subsequent elements get appended as suffix.
Is this somewhere in the java api docs? Or just very obvious string or add operator behavior which I am not seeing. Any of your valuable insights will be appreciated.
Here is the code snippet:
public static void main(String[] args) {
System.out.println(1+2);
System.out.println(1+2+"3");
System.out.println("1"+2+3);
System.out.println("1"+2+"3");
System.out.println("1"+2);
}
// The Console output:
// 3
// 33
// 123
// 123
// 12
I guess the Java specification explains it best:
The + operator is syntactically left-associative, no matter whether it
is determined by type analysis to represent string concatenation or
numeric addition. In some cases care is required to get the desired
result. For example, the expression:
a + b + c
is always regarded as meaning:
(a + b) + c
So, if a was a String, then it concatenates with b. The result would be of String type, hence it continues to concatenate with c.
I also found this interesting. I haven't worked too much in java recently but I found out a little bit of info that might be helpful through playing with it.
I think this has to do with automatic Type-casting that java does.
System.out.println("1"+2+3);
Prints 123 as you said. Since "1" is casted as string, Java assumes since the first one was a string, the ones following will be a string for concatenation unless otherwise noted
Although, this result does print 15 when you define the type
System.out.println("1" + (int)(2+3));
In that case, it can complete the operation before concatenating.
So I think java is assuming if the first one is a String, that the rest are going to be strings and to concatenate them.
EDIT: you can see some info about automatic type-conversion on oracle's website here
The + operator is overloaded in the compiler. If both operands are numeric, + is addition. If either or both operands are String, + is string concatenation. (If one operand is String and the other is numeric, the number is cast to a String). Finally, + binds left-to-right.
All this causes a compound formula a + b + c + ... to do addition left-to-right until it hits the first string operand, at which point it switches to string concatenation for the remainder of the formula. So...
"1" + 2 + 3 + 4 = 1234 /* cat cat cat */
1 + "2" + 3 + 4 = 1234 /* cat cat cat */
1 + 2 + "3" + 4 = 334 /* add cat cat */
1 + 2 + 3 + "4" = 64 /* add add cat */
Thats interesting part of string.
When a String is added to any other data type, the resultant value is a String.The other variable is also converted to a String and then concatenated. However, when two integers are operated with a + sign, the + acts as an addition operator and not a concatenation operator.
If the expression within the println() or print() method contains parentheses, then the value within the parentheses is evaluated first. Consider the following example:
int a = 5;
int b = 6;
System.out.println(a + b); // Output will be: 11
System.out.println("5" + "6"); // Output will be: 56
System.out.println("" + a + b); // Output will be: 56
System.out.println(5 + 6 + a + " " + b + a); // Output will be: 16 65
System.out.println("Result: " + a + b); // Output will be: 56
System.out.println("Result: " + (a + b)); // Output will be: 11
You can see the difference between last two sysout statements

understanding the java string with add operator

I am trying to understand how the compiler views the following print statements. It is simple yet a bit intriguing.
This prints the added value. Convincing enough.
System.out.println(1+2); //output: 3
The output from the following looks convincing as well:
System.out.println(1+2+"3");//output: 33
My question (based on the behavior above) is here.
System.out.println("1"+2+3);//Should be 15 right? NO. It is 123.
I tried few other such statements which were along the same lines. I was able to see one two clear behaviors.
If integers are at the front, without the quotes, they are added and subsequent integers are just appended as suffix to the added values from the front.
if the statement starts with string, under quotes, then all other subsequent elements get appended as suffix.
Is this somewhere in the java api docs? Or just very obvious string or add operator behavior which I am not seeing. Any of your valuable insights will be appreciated.
Here is the code snippet:
public static void main(String[] args) {
System.out.println(1+2);
System.out.println(1+2+"3");
System.out.println("1"+2+3);
System.out.println("1"+2+"3");
System.out.println("1"+2);
}
// The Console output:
// 3
// 33
// 123
// 123
// 12
I guess the Java specification explains it best:
The + operator is syntactically left-associative, no matter whether it
is determined by type analysis to represent string concatenation or
numeric addition. In some cases care is required to get the desired
result. For example, the expression:
a + b + c
is always regarded as meaning:
(a + b) + c
So, if a was a String, then it concatenates with b. The result would be of String type, hence it continues to concatenate with c.
I also found this interesting. I haven't worked too much in java recently but I found out a little bit of info that might be helpful through playing with it.
I think this has to do with automatic Type-casting that java does.
System.out.println("1"+2+3);
Prints 123 as you said. Since "1" is casted as string, Java assumes since the first one was a string, the ones following will be a string for concatenation unless otherwise noted
Although, this result does print 15 when you define the type
System.out.println("1" + (int)(2+3));
In that case, it can complete the operation before concatenating.
So I think java is assuming if the first one is a String, that the rest are going to be strings and to concatenate them.
EDIT: you can see some info about automatic type-conversion on oracle's website here
The + operator is overloaded in the compiler. If both operands are numeric, + is addition. If either or both operands are String, + is string concatenation. (If one operand is String and the other is numeric, the number is cast to a String). Finally, + binds left-to-right.
All this causes a compound formula a + b + c + ... to do addition left-to-right until it hits the first string operand, at which point it switches to string concatenation for the remainder of the formula. So...
"1" + 2 + 3 + 4 = 1234 /* cat cat cat */
1 + "2" + 3 + 4 = 1234 /* cat cat cat */
1 + 2 + "3" + 4 = 334 /* add cat cat */
1 + 2 + 3 + "4" = 64 /* add add cat */
Thats interesting part of string.
When a String is added to any other data type, the resultant value is a String.The other variable is also converted to a String and then concatenated. However, when two integers are operated with a + sign, the + acts as an addition operator and not a concatenation operator.
If the expression within the println() or print() method contains parentheses, then the value within the parentheses is evaluated first. Consider the following example:
int a = 5;
int b = 6;
System.out.println(a + b); // Output will be: 11
System.out.println("5" + "6"); // Output will be: 56
System.out.println("" + a + b); // Output will be: 56
System.out.println(5 + 6 + a + " " + b + a); // Output will be: 16 65
System.out.println("Result: " + a + b); // Output will be: 56
System.out.println("Result: " + (a + b)); // Output will be: 11
You can see the difference between last two sysout statements

One plus plus two compiles unexpectedly [duplicate]

This question already has answers here:
Why does this Java code with "+ +" compile?
(8 answers)
Closed 8 years ago.
So, I expect this not to compile, and it doesn't:
// the two is inc'd, so reduces symbolically to println(int int)
// which is a compile error
System.out.println(1 ++ 2);
But this does:
System.out.println(1 + + 2); // returns three
What gives? Shouldn't it also not compile?
Also, this question is very hard to search for because of the operators..
Java is interpreting the working 1 + + 2 as 1 plus positive 2. See the Unary operator section.
From the Specification, on Lexical Translations
The longest possible translation is used at each step, even if the
result does not ultimately make a correct program while another
lexical translation would. There is one exception: if lexical
translation occurs in a type context (§4.11) and the input stream has
two or more consecutive > characters that are followed by a non->
character, then each > character must be translated to the token for
the numerical comparison operator >.
(Also known as maximal munch.)
The ++ is interpreted as a postfix increment operator which cannot be applied to an integer literal, thus the compiler error.
While
1 + + 2
each character is interpreted separately. 1 is an integer literal, + is the additive operator, + is the unary plus operator, and 2 is an integer literal. The whole expression is equivalent to
1 + (+2)
which is easier to read.
In Java/C++/C ++ is not same as + +. ++/-- are the Increment/Decrement operator.
The first case does not work because it does not apply to literals (1 or 2).
Even then it would not be a valid statement, Neither 1++ 2 nor 1 ++2 are valid statement in Java. The second example works because it is interpreted as 1 + (+2). The Java lexer ignores white space. ​In the same way this is valid :
1 + + + 2 --> 1 + (+ (+2))
Or
1 + + + + + + + + + + + + + + + + + + + + + + + + + + + 2
​It works only because + is a unary operator. It does not work for strings as below :
"a" + + "b" // does not work because +"b" is not valid.
Similarly it is not valid with multiplication
1 * * 2 // does not work because *2 is not valid.
Sometimes it's easier to see a problem using variables.
Your snippet could be rewritten as:
int a = 1;
int b = +2;
System.out.println(a + b);
Now, you can easily see that the second + operator is used to indicate a positive value.
You could also have written +1 + +2.
The - operator could be used to negate an expression.
+ and - are unary operators.
The message is:
Main.java:14: error: ')' expected
System.out.println(1 ++ 2);
^
The 1 ++ 2 statement is parsed as 1 followed by ++ followed by 2. This is interpreted as 1++ and 2 creating a syntax error (and not an unexpected type error; in fact, you will get the same error if you used variables e.g. i ++ j).
The 1 + + 2 statement on the other hand is parsed as 1 followed by + followed by +2 which compiles as expected. The space between the two operators separates the two operators.

What do double quotes in a Java expression mean?

What do double quotes mean in a Java expression?
I have:
"2 + 2" + 3 + 4
"hello 34" + 2 * 4
1 + ""
Can someone explain how these expressions are evaluated, and what the purpose of the last one is?
anything inside " " will become String. and string + Int = String .for example,
"2 + 2" + 3 + 4
you will get 2 + 234
in your question,
"2 + 2" + 3 + 4 +"hello 34" + 2 * 4 //i added '+' between '4' and 'hello' since there is an error in expression
will be evaluated like this:
1. output = "2 + 2" + 3 + 4 +"hello 34" + 2 * 4
2. output = "2 + 2" + 3 + 4 +"hello 34" + 8 //operation '*' evaluated first
3. output = "2 + 23" + 4 +"hello 34" + 8
4. output = "2 + 234" +"hello 34" + 8
5. output = "2 + 234hello 34" + 8
6. output = "2 + 234hello 348"
The + operator has two meanings in Java.
When both operands are numeric1, it means arithmetic addition.
When either operand has type String, it means string concatenation.
In the string concatenation case, a non-string argument is first to a string. The process is called string conversion and is specified in JLS 5.11.1. The procedure is as follows:
A primitive type is converted to a string as if it was boxed, and the toString() was called on the boxed value.
A null is converted to the string "null".
Any other reference type is converted by calling its toString().
The complete semantics of + concatenation are specified in JLS 15.8.1.
#Baby's answer explains how this works for the first example in the Question, and the second example is similar. (Note that * has a higher precedence than + so 2 * 4 is evaluated as a multiplication and 8 is then used in the concatenation.)
The third example is a common Java idiom for converting a number to a String. Thus
1 + "" -> "1" // equivalent to Integer.toString(1)
1.0 + "" -> "1.0" // equivalent to Double.toString(1.0)
On the face of it, the versions in comments should be more efficient. Concatenating with "" would appear to be performing an unnecessary concatenation. However, if you read the wording of the spec carefully, it is apparent that the Java compilers are permitted to optimize the first form to the second. It is my understanding that they do ... in recent versions of Java.
Many people consider the ... + "" idiom to be bad practice. However it is common enough that you need to recognize it when you encounter it.
1 - In this context, this means any integral or floating point primitive type, or any of the matching wrapper types. The complete set is byte, short, char, int, long, float, double, java.lang.Byte, java.lang.Short, java.lang.Character, java.lang.Integer, java.lang.Long, java.lang.Float, and java.lang.Double.

Java : large integer numbers error

I am trying to do the following math equation in Java:
(44334*(220*220))+ (81744*220) + 39416)
When I enter the same equation in WolframAlpha (or in Google) I get:
2163788696
In java I get negative number..
I have been struggling to find out why this is happening but with no luck.
I also tried saving the answer in a BigInteger, but then I get negative values because the digits are too large.
What should I do?
EDIT: To deal with the integer wrap-around, use a long:
System.out.println("Result: " +
(44334L * 220 * 220 + 81744 * 220 + 39416)); // 2163788696
The plus operator is left-associative (whether it's being used for string concatenation or addition), so if the entire arithmetic expression weren't parenthesized, it would be concatenating the results of the sub-expressions as individual strings from left to right.
The left operand determines whether + is used for string concatenation or addition. In this case, the first operand is a string, so the right side ((44334*(220*220))) is converted into a string as well. The result of the first + operator is a string and is used as the left side of another + string concatenation operation. the next operand ((81744*220)) gets converted to a string again.
You can put parentheses around the entire arithmetic expression to avoid that.
Right now, what you are doing is equivalent to:
System.out.println(("result="+(44334*220*220)) + (81744*220 + 39416) );
// = "result=2145765600" + 18023096
// = "result=214576560018023096"
Parentheses are important! Here is your code fixed:
System.out.println("result=" + (44334*220*220+ 81744*220 + 39416) );
// = "result=2163788696"
EDIT:
Also beware of automatic int casting. Use longs because your result is bigger than MAX_INT (but smaller than MAX_LONG which is 9223372036854775807).
(long)((long)44334*220*220 + (long)81744*220 + 39416)
Or put the suffix L after your numbers (so they're considered as longs).
The problem is due to the fact that the expression is evaluated from left to right. The first value is of type string, so the + operator then becomes the string concatenation operator instead of the mathmatical addition operator. The expressions (44334*(220*220)) and (81744*220) are then evaluated and converted to strings leading to an incorrect result. If you surround the entire expression with parentheses, the result is calculated properly and you see the correct result.
For the BigInteger version, try this, it will work correctly
BigInteger a = new BigInteger("44334").multiply(new BigInteger("220").multiply(new BigInteger("220")));
BigInteger b = new BigInteger("81744").multiply(new BigInteger("220"));
BigInteger c = new BigInteger("39416");
c = c.add(a).add(b);
System.out.println("resultVersA="+(44334*(220*220))+ (81744*220) + 39416 );
System.out.println("resultVersB="+ c);
The result will be:
resultVersA=21457656001798368039416
resultVersB=2163788696
The problem is that the + operator in Java is overloaded. It can mean either string concatenation or numeric addition. What is going on is that some of the + operations are being treated as string concatenations rather that numerical additions.
You need to either add a set of parentheses around the expression,
System.out.println("result="+((44334*(220*220))+ (81744*220) + 39416));
or use a temporary variable.
int res = (44334*(220*220))+ (81744*220) + 39416;
System.out.println("result="+res);
"The rules" that Java uses to determine the meaning of + are roughly as follows:
If the type of the left OR right operand is String, then the + means string concatenation.
If the types of both the left AND right operands are primitive numeric types or numeric wrapper types, then the + means a numeric addition.
Otherwise this is a compilation error.
The other problem here is that 2163788696 is greater than the largest int value - 2147483647. So to get the right answer (without overflow), you need to tell Java to use long arithmetic; e.g.
System.out.println("result=" + ((44334L * (220 * 220)) + (81744 * 220) + 39416));
If you don't then result will be a negative number ... in this example.
You could also use BigInteger, but it is a bit cumbersome, and long will do just fine here.
Just put an L after every number you write.
(44334L*(220L*220L))+ (81744L*220L) + 39416L

Categories

Resources