I was doing java assignment and I ran into this code.
int x=3, y=5;
System.out.println(x + y + " = " + y + x);
and the output is "8=53". Why does the first x+y gets evaluated and the last y and x expression gets printed? Left me wondering. Thanx in advance guys.
Remember that in Java, an operator (like +) can be overloaded. That means it will do different things, depending on its operands. For +, there are (at least) two choices: integer addition and string concatenation.
Which overload is chosen depends more so on the left-hand-side operand. Also, string concatenation with a non-string operand can cause automatic conversion to a string.
The whole thing will be evaluated left-to-right like this:
x + y + " = " + y + x
3 + 5 + " = " + 3 + 5 // 3+5 chooses the integer addition overload of +
8 + " = " + 3 + 5 // 8 + " = " chooses string concatenation
"8" + " = " + 3 + 5 // so 8 is converted to "8" first
"8 = " + 3 + 5 // and then concatenated with " = "
"8 = " + "3" + 5 // now 3 is converted to "3"
"8 = 3" + 5 // and concatenated with "8 ="
"8 = 3" + "5" // finally 5 is converted to "5"
"8 = 35" // and concatenated with the rest
FWIW, it's ambiguity like this that leads me to dislike implicit conversions1.
1 - In C#. I love it in Python :-)
output is "8=53". Why does the first x+y gets evaluated and the last
y and x expression gets printed?
Because first x + y are not appended with a string so integer calculation is done. Second ones are appended to a string because of " = " + and hence they are printed as individual values.
To prove this just do:
System.out.println("" + x + y + " = " + x + y);
and the output will be:
35 = 35
The first part is getting interpreted as integer addition, but in the second part (as you have introduced a string) it is getting interpreted and string concatenation.
Assuming you want 8 = 8
try
System.out.println(x + y + " = " + (y + x));
if you want 3 + 5 = 5 + 3
then I would use String.format as
in
System.out.println (String.format ("%d + %d = %d + %d", x, y, y, x));
The reason the output is "8 = 53" is because:
x + y + " = " + y + x
Is calculated from left to right so, if we break it down piece by piece:
x + y = 8
8 + " = " = "8 = "
"8 = " + y = "8 = 5"
"8 = 5" + x = "8 = 53"
That is how the compiler gets your answer :)
The first + is between two numbers so the result is eight. The 2nd have strings on either side of them so numbers get converted to strings and concatenated together. The plus operator binds tightest to the left, and gets evaluated left to right. If you wanted the last addition to be numerical then the expression should be in brackets ( ).
Related
Java
int x = 5;
System.out.println(" x + 5 is " + x + 5);//correct
System.out.println("x += 5 is " + x += 5);// why wrong?
Even though, these 2 println is including calculation but why second println is error.Thanks
What you are doing causes an error because the + is seen as an operator to seperate parts of the string. Try placing that part between brackets like:
System.out.println("x += 5 is " + (x += 5));
This might fix it as you exclude the + from the string. Hope this helps you a bit, and that I am correct in my statement.
I have been given the following question:
Consider the following method. What should it return if n == 3?
public static String recEx(int n) {
if (n <= 0)
return "";
return recEx(n - 3) + n + recEx(n - 2) + n;
}
The answer is 3113. How and what do you do to achieve this answer?
Simply put a System.out.println(n) at the top of the method and you will see.
recEx(3) calls
recEx(0)+3+recEx(1)+3
where recEx(1) is
""+1+""+1
The best approach is using a pencil and a paper and start drawing things.
_recEx(3)_
/ \
/ recEx(1)
recEx(0) / \
/ recEx(-2) recEx(-1)
""
When the value is <= 0, an empty String is returned, this value is pushed back to the caller... and that's the recursion! It's good to begin with smaller example, say n = 2, or even n = 1, try to understand it and then apply it on bigger numbers.
A good practice is debugging your code and carefully following the debugger, step by step, see all the values and trying to understand them.
recEx(3) = recEx(0) + 3 + recEx(1) + 3
recEx(0) = ""
recEx(1) = recEx(-2) + 1 + recEx(-1) + 1
recEx(-2) = ""
recEx(-1) = ""
So the answer is:
recEx(3) = recEx(0) + 3 + recEx(1) + 3
recEx(3) = "" + 3 + recEx(-2) + 1 + recEx(-1) + 1 + 3
recEx(3) = "" + 3 + "" + 1 + "" + 1 + 3
recEx(3) = "3113"
Start with the base case: n <= 0
recEx(0) ; ==> ""
When you look at the default case it will always reduce n on each recursion. Thus you should try n == 1 and use the knowledge that when n <= 0 it can be replaced with "".
recEx(1); ==>
recEx(-2) + 1 + recEx(-1) + 1; ==>
"" + 1 + "" + 1; ==>
"11"
Then you try n == 2
recEx(2); ==>
recEx(-1) + 2 + recEx(0) + 2; ==>
"" + 2 + "" + 2; ==>
"22"
Then you try n == 3. Here you use you prior knowledge of recEc(1)
recEx(3); ==>
recEx(0) + 3 + recEx(1) + 3; ==>
"" + 3 + "11" + 3; ==>
"3113"
There you go.. As you can see I go from the simplest and go backwards. I'm using substitution rules saying you can replace the result of a known result with a method call. As long as the method is functional (doesn't rely on enything else than arguments) you can do this.
For fun whats recEx(5) ? Well it must be like this:
recEx(5); ==>
recEx(2) + 5 + recEx(3) + 5; ==>
"22" + 5 + "3113" + 5 ==>
"22531135"
It's quite simple when you already know the answers for recEx(2) and recEx(3).
Calculating recEx(3) starting with the default case works the same except you need to stop what you are doing at each level to calculate the result of the recursive call. Remember to keep track of which n you have calculated and it's result so you don't need to do same n several times like the computer actually does.
I find doing it the way I presented here much easier since you don't need to do several things in the same time.
You have to trace it:
when n=3
will call again for:
recEx(0) + 3 + recEc(1) + 3
recEx(0) // will return empty string
and if you call for recEx(1)
recEx(-2) + 1 + recEx(-1) + 1
recEx(-2) // will return empty string
recEx(-1) // will return empty string
so first will retun to calculate
recEx(-2) + 1 + recEx(-1) + 1 = "" + 1 + "" + 1 = "11"
and this result will back to the first caller
recEx(0) + 3 + recEc(1) + 3 = "" + 3 + "11" + 3 = "3113"
and to print the result to console:
System.out.println(recEx(3));
System.out.println(7 + 5 + " ");
This prints out 12, but in another order
System.out.println(" " + 5 + 7);
it prints out 57. Why is this?
Firstly, this has nothing to do with System.out.println. You'll see exactly the same effect if you use:
String x = 7 + 5 + "";
String y = " " + 5 + 7;
It's got everything to do with associativity. The + operator is left-associative, so the above two statements are equivalent to:
String x = (7 + 5) + "";
String y = (" " + 5) + 7;
Now look at the results of the first expression in each case: 7 + 5 is just 12, as int... whereas " " + 5 is "5" (a string).
Or to break it down further:
int x1 = 7 + 5; // 12 (integer addition)
String x = x1 + ""; // "12" (conversion to string, then string concatenation)
String y1 = " " + 5; // "5" (conversion to string, then string concatenation)
String y = y1 + 7; // "57" (conversion to string, then string concatenation)
Justification: JLS 15.18 (additive operators):
The additive operators have the same precedence and are syntactically left-associative (they group left-to-right).
Easy. System.out.println(7 + 5 + " ") is viewed as a mathematical equation, whereas System.out.println(" " + 5 + 7) whereas having the space beforehand, Java (I'm assuming) views it as a string. Thus 'concatenating' the two.
public class Test {
public static void main(String[] args) {
int number1 = 4;
int number2 = 5;
System.out.println( number1 + "Score:" + (number1 + number2) + number1 );
}
}
The output of the above is:
4Score: 94
Why is this? If there is no "score" in there, I understand the result from it, but this I don't know why. number1 and Score: outputs individually first, so then why is it effecting the result to be 94?
You have:
public static void main(String[] args) {
int number1 = 4;
int number2 = 5;
System.out.println( number1 + "Score:" + (number1 + number2) + number1);
}
This is outputting exactly what you told it to output, essentially:
"4" + "Score:" + "9" + "4"
The + operator when used with a string will convert the non-String operands to strings and concatenate the strings together. When + is used with all numeric operands, it is an arithmetic + and just adds the values together.
By putting (number1 + number2) in parentheses, you cause that to be evaluated first, and since both operands are integers, it behaves as an arithmetic + thats adds those two numbers together (producing 9). That result is then converted to a string and concatenated to everything else. It's essentially a shortcut for:
int number1 = 4;
int number2 = 5;
System.out.println( Integer.toString(number1) +
"Score:" +
Integer.toString(number1 + number2) +
Integer.toString(number1) );
If you remove "Score:", then all of the operands are integers, and so all of the + operators are arithmetic addition, and it just sums all the numbers -- i.e. a shortcut for:
System.out.println( Integer.toString(number1 + (number1 + number2) + number1) );
If you want more technical details of the + operator as related to strings vs. numbers, see Section 15.18 of the JLS (15.18.1 describes behavior for strings, 15.18.2 describes behavior for numeric types).
As an aside, the + operator is always left-associative no matter what types the operands are (described in 15.18.1). So the result of the following may surprise you:
System.out.println(1 + 2 + "string" + 1 + 2);
Spoiler (mouse over):
3string12
See http://ideone.com/P11aMI for some more working examples.
It's to do with operator precedence and the overloading of the + operator. If both sides are numbers, then the + operator performs addition:
number1 + number2
results in 9, which is evaluated first (as it's in brackets).
Then as the rest of it has the same precedence, it is overloaded to string concatenation, in left to right order. If one or all of the arguments to the operator are not numbers, they will all be implicitly converted into strings. We start off with:
4 + "Score:" + (4 + 5) + 4
As the brackets are evaluated first, we then get this:
4 + "Score:" + 9 + 4
Which becomes
"4Score:" + 9 + 4
Then
"4Score:9" + 4
And your final result will be
"4Score:94"
just as you got.
the subterm number1 + number2 is treated as an integer. So the sum could be calculated: 9. Using it as a string parameter results in an automatic cast to String, therefore the concatenation of strings is used: number1 + "Score:" + "9" + number1
System.out.println( number1 + "Score:" + (number1 + number2) + number1))
This prints out the following values (the one in the bracket results in an arithmetic sum :
4 + "Score:" + (4+5) + 4
which is
4Score:94
System.out.println( number1 + "Score:" + (number1 + number2) + number1));
it will be step by step as
1) System.out.println( 4 + "Score:" + 9 + 4));
2) System.out.println( "4Score:" + 9 + 4));
3) System.out.println( "4Score:9" + 4));
Then it shows output as
"4Score:94"
int i = 0;
int k = Integer.parseInt("12");
int j = k;
System.out.println(i+1 + " " + j+1);
Strangely the output received is
1 121
I can not figure out this basic difference. Please help me.
Use brackets as follows
System.out.println((i+1) + " " + (j+1));
From the docs
The + operator is syntactically left-associative, no matter whether it
is later determined by type analysis to represent string concatenation
or 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
Extending this to your scenario
i+1 + " " + j+1
it becomes
(((i + 1) + " ") + j)+1
Since i is an int so (i + 1) = 1 , simple addition
" " is a String hence ((i + 1) + " ") = 1 WITH SPACE (String concatenation)
Similarly when j and last 1 is added, its being added to a String hence String concatenation takes place, which justifies the output that you are getting.
See
JLS 15.18.1 String Concatenation Operator +
that is beacuse of " ".
whenever a String comes, java doesnt do any calculations after that and just append it as string.
So in your case, i+1 is computed to 1, but " " + j+1 has string in it. So, it just appended together to form 121
The reason you see this behavior is that the sequence of + operators is evaluated left-to-right. So it is evaluated as if parenthesized:
System.out.println((((i + 1) + " ") + j) + 1);
The first operator adds two int values and produces an int value. The next + adds an int to a String and produces a String. After that, everything is string concatenation. You can introduce your own parentheses to get the result you want.
int i = 0;
int k = Integer.parseInt("12");
int j = k;
System.out.println(i+1 + " " + (j+1));
basically when you put + " " + after this java just appends values as string.
and when you put (j+1) in brackets then its precedence gets higher and it is executes it first and perform sum operation.
When you use " " The expression after that gets evaluated as string.
Using brackets ( and ) around an expression can solve the problem in hand.
System.out.println(i+1 + " " + (j+1));
+ operator is overloaded for addition and String concatenation what you're doing is String concatenation and not addition.. Use brackets for performing addition.
parseint will basically return int (Look at Java API), and there is only one int type in Java. in this example you used " ", where java will treat it as string. in any operation make sure you dont mix up strings with calculations. Always use parenthesis to separate String from calculations.
It happens because the + operator has left associativity and has an overloaded function with strings, so when you have this
int i = 0;
int k = Integer.parseInt("12");
int j = k;
i+1 + " " + j+1
it first sums
i + 1 which gives 1 then it sums 1 + " ", which uses the overloading function of it to concatenate 1 and " " so it gives a string with the value of "1 ". After that it sums "1 " + j and since one of the operands is a string, it does the same behavior and so on.
Interger.parseInt (String str) is a wrapper class method which is used to convert String obj type to primitive data type (int). this are generally used in collection frame work for converting primitive data type to object and vice versa