The purpose of double quotes ("") with integer concatenation - java

I just started the "Head First Java" book. There is an exercise that is tripping me up due to the double quotes ("") with no space in the code below. I think I figured it out, but it doesn't look like the book explains it and I would like to make sure I am correct moving forward.
Is the purpose of the double quotes ("") in the code below to concatenate the two integers (x and y) and prevent the + operator from performing addition for the output? That's what it seems.
The OUTPUT for the code below is: 00 11 21 32 42.
I deleted the double quotes and the output gives me: 0 2 3 5 6.
class Test
{
public static void main (String[] args)
{
int x = 0;
int y = 0;
while ( x < 5)
{
y = x - y;
System.out.print(x + "" + y + " ");
x = x + 1;
}
}
}

To answer your direct question: you are correct that the "" is there to turn the + into a concatenation, rather than addition. But I'll give a few more details as to what's going on here.
It's perhaps a little bad of the authors of the book to use this without explaining, since this appears to be a key thing in the exercise (even a brief footnote saying "this is just an easy way to convert to a String"); but it's one of those things most Java programmers wouldn't even think about needing to explain, so easy to miss; or, perhaps they did explain it earlier, and you just missed it, because of the throw-away nature of the explanation. No accusations; it's just what it is.
We're trying to evaluate the expression x + "" + y + " " in order to print it. Because + is left-associative, this is evaluated as
((x + "") + y) + " "
So, in terms of the effect of including "", the question is how the subexpression x + "" will be evaluated. If the "" had been omitted, it would be evaluated as
(x + y) + " "
There is no separate operator for "numeric addition" and "string concatenation" in Java: both use +. So, Java uses a simple rule to decide between the two:
If the type of either operand of a + operator is String, then the operation is string concatenation.
As such, x + "" is string concatenation, but x + y would be numeric addition.
If you look into the specifics of string concatenation:
If only one operand expression is of type String, then string conversion (§5.1.11) is performed on the other operand to produce a string at run time.
So this is saying that the int in int + String has to be converted to a string, in order to concatenate it with another string, which is pretty reasonable. And this string conversion is done using:
If T is byte, short, or int, then use new Integer(x).
...
the conversion is performed as if by an invocation of the toString method of the referenced object with no arguments
("as if" is just wiggle room to say you don't actually have to invoke new Integer(x) - implementations could use Integer.toString(x), or some other method, instead).
Then, concatenation is defined as:
The characters of the left-hand operand precede the characters of the right-hand operand in the newly created string.
Given that "" has no characters, it is trivially true that someString + "" will have the same characters as someString (*).
So, int + "" (or "" + int) is simply a syntactic trick to convert the int to a String. There is no other effect of doing this. It's just less verbose to write this than Integer.toString(x) or new Integer(x).toString().
It's also worth pointing out that it would work the same had it been "" + x + y + " ". But that's perhaps less clear to the human eye that the x and y won't be added.
(*) The slight detail here is that concatenation results in a new string (unless the two operands are constant expressions, in which case the concatenation is done at compile time), i.e. someString + "" != someString, even though (someString + "").equals(someString).

Is the purpose of the double quotes ("") in the code below to
concatenate the two integers (x and y) and prevent the + operator from
performing addition for the output?
That's exactly what it is. The alternative would be something like
print(String.valueOf(x) + String.valueOf(y) + " ")
which is a lot less readable. The String type can be forced also in the beginning, as in "" + x + y + " ", just as long as we're dealing with Strings before we start to use the + operator.

Related

Why use " " and not ' ' for outputting a blank? [duplicate]

This question already has answers here:
Is there a difference between single and double quotes in Java?
(4 answers)
Closed 3 years ago.
Is there any reason why you may want to use " " and not ' ' to output blanks in Java (any version)?
In "Data Structures and Problem Solving Using Java (4th Edition)" by Mark Allen Weiss, it says that it is a common error to not use " " instead of ' ': i.e. We should use " ".
As far as I know, there are no differences between the two.
Trying:
System.out.println("a b c" + ' ' + "d e f");
System.out.println("a b c" + " " + "d e f");
There seems to be no difference in the output.
With your example if may have no effect. However, there are cases where it matters.
char is an integral type, and
System.out.println(1 + ' ' + 2); //output: 35 because 1 + 32 + 2
produces a different result from
System.out.println(1 + " " + 2); //output: 1 2
So you should make sure you know the difference between ' ' and " ".
I imagine that the context of the advice in the book gives some indication of what situation it is talking about.
It is because + operator has two meanings in Java
concatenation if at least one operand is String like Str + ... or ... + Str
addition if both operands are numeric types:
all primitives, except boolean (no in Java true and false are not equivalents of 1 and 0),
BUT including char which numeric value is position of character in Unicode Table like 'A' is 65 and space ' ' is 32.
wrapper classes for numeric primitive types like Integer, Double
So if you have num + Str operator + will represent concatenation and you will get String.
But in case of num + char operator + will represent addition and will return numeric value like System.out.println(1+' ') will be treated as 1+32 so 33 will be printed.
So if you use " " with + you are guaranteed that it will be concatenation, while meaning of + with ' ' will depend on second argument.
We use single quotes for literal chars and double quotes for literal Strings. So you're going to add them together with this:
System.out.println("a b c" + ' ' + "d e f");
but there is no error in it. You can use " " or ' ' to output a space.
The reason your Java book tells you that double quotes is better than single quotes is that ' ' is a char, and " " is a String. This is built-in java behaviour.
char is a java primitive, like an int or a float. String is a supplied object type, not a primitive. When you put " " in your code, java interprets this as an instance of java.lang.String.
You're right that it has no practical effect in your example though. That's because when you concatenate strings and characters, java automatically converts the whole thing to a String (the + operator does this). You can also concatenate other primitives in this way.
However, these are actually quite different in Java, and you can prove this with a simple test:
#Test
public void testCharVsString(){
assertTrue(" ".equals(' '));
}
The above test will fail, as these two objects are not the same.
As a general rule it's OK to stick with Strings when representing characters. char is useful for more advanced coding tasks.

Additive Operator (+) Performing Concatenation Instead of Addition [duplicate]

This question already has answers here:
What is the precedence of the + (plus) operator in Java?
(4 answers)
Closed 3 years ago.
I am new to Java. When I am processing through the loop below I want to show the loop's counter value being incremented by 1. When I kept the below code of that I am getting the value as like of concatenate with 1 with the counter value. Why is the System.out.println working with concatenation instead of addition?
for (c = 0; c < Size; c++) {
System.out.println("here the problem " + c+1 + " Case");
}
The + operator is overloaded for both concatenation and additon, and both operators have the same precedence, so the operations are evaluated from left to right.
Starting at the left, the first operand encountered is a String "here the problem", so the operator knows that it should perform concatenation. It proceeds to concatenate c to that String, yielding a new String.
The second + therefore is operating on that resulting String, and 1, so once again it does concatenation.
If you want to specifically control the order of the operations, and have c + 1 evaluated before "here the problem" + c then you need to enclose the operation in parentheses:
"here the problem " + (c + 1) + " Case"
Try this
for (c = 0; c < Size; c++) {
System.out.println("here the problem " + (c+1) + " Case");
}
As this always try to evaluate the expression in the parenthesis before string concatenation
It's not a matter of how System.out.println works.
Java treats your statement as concatenation.
Because when you use + with string other variable will be treated as string and java will perform concatenation

Difference between String.valueOf(int i) and printing only i

See the below code snippet:
int count = 0;
String query = "getQuery";
String query1 = "getQuery";
final String PARAMETER = "param";
query += "&" + PARAMETER + "=" + String.valueOf(count);
query1 += "&" + PARAMETER + "=" + count;
System.out.println("Cast to String=>"+query);
System.out.println("Without casting=>"+query1);
Got the both output exactly same. So I am wondering why this has been used when we can get the same result by using only count.
I got some link but did not found exactly same confusion.
This is well explained in the JLS - 15.18.1. String Concatenation Operator +:
If only one operand expression is of type String, then string conversion (§5.1.11) is performed on the other operand to produce a string at run time.
You should note the following:
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.
If you write 1 + 2 + " fiddlers" the result will be
3 fiddlers
However, writing "fiddlers " + 1 + 2 yields:
fiddlers 12
Java compiler plays a little trick when it sees operator + applied to a String and a non-string: it null-checks the object, calls toString() on it, and then performs string concatenation.
That is what's happening when you write this:
query1 += "&" + PARAMETER + "=" + count;
// ^^^ ^^^^^^^^^ ^^^
You can certainly do this when the default conversion to String is what you want.
However, if you do this
String s = count; // <<== Error
the compiler is not going to compile this, because there is no concatenation. In this situation you would want to use valueOf:
String s = String.valueOf(count); // <<== Compiles fine
String.valueOf(int) actually calls Integer.toString().
So, it is used to convert an int to a String elegantly. As, doing i+"" is IMNSHO, not quite elegant.
Moreover, when you print any number directly, it actually calls the toString() method of its Wrapper class, and the prints the string.

Java: Is "9" appearing in my run an Eclipse bug?

While writing my code for a computer dating assignment in which we see the compatibility of an array of four objects, my code printed strangely. (Eclipse didn't give me an error/warning at first).
Code:
System.out.print("Fit between " + profile1.getTitle() + " and " + profile2.getTitle() + ": \n " +
+ '\t' + profile1.fitValue(profile2) + '\n');
When I tried to print things out, they appeared like this:
Fit between Elizabeth Bennett and Elizabeth Bennett:
90.0
Fit between Elizabeth Bennett and Fitzwilliam Darcy:
90.55
Fit between Elizabeth Bennett and Romeo Montague:
90.3
Fit between Elizabeth Bennett and Juliet Capulet:
90.0
.......................................................so on so forth.
There was a "9" appearing in front of my numbers.
I found the problem later: I had two concatenating operators ("+") after my "\n". So I changed my code, deleting the extraneous "+".
New code:
System.out.print("Fit between " + profile1.getTitle() + " and " + profile2.getTitle() + ": \n " +
'\t' + profile1.fitValue(profile2) + '\n');
New correct run:
Fit between Elizabeth Bennett and Elizabeth Bennett:
0.0
Fit between Elizabeth Bennett and Fitzwilliam Darcy:
0.55
Fit between Elizabeth Bennett and Romeo Montague:
0.3
Fit between Elizabeth Bennett and Juliet Capulet:
0.0
..............................................so on so forth.
Though I've thankfully found my problem, I want to know what exactly is causing this to happen. Is there some sort of eclipse shorthand that leads to the "9"'s appearance? Or is this due to some eclipse bug? I'm still a beginner at java, so I can't make a solid conclusion.
I tried modifying my code slightly to see how Eclipse would react (I deleted the space between my original "+ +"):
System.out.print("Fit between " + profile1.getTitle() + " and " + profile2.getTitle() + ": \n " ++
'\t' + profile1.fitValue(profile2) + '\n');
Eclipse gave me this warning:
Multiple markers at this line
Syntax error on token "++", +
expected
Invalid argument to operation ++/--
This makes sense, because ++ on its own is an operator of sorts.
Interestingly, however, if I put a space between the "++", then the warning disappears.
I didn't paste my entire code for the sake of readability, but if necessary, I can edit and add it in.
Some clarification regarding this would be helpful. Thank you.
No, it's not a bug. It's unusual, but it's not a bug.
The first thing to do is simplify the example massively:
public class Test {
public static void main(String[] args) {
String start = "Start";
String end = "End";
System.out.println(start + '\t' + end);
System.out.println(start + +'\t' + end);
}
}
Result:
Start End
Start9End
Now admittedly I'm using strings for both start and end, but due to + being left-associative, that doesn't make any difference here. (If start were an integer, the first binary + operator would be integer addition in both cases.)
Basically, the extra + ends up being a unary + operator with '\t' as the operand. Unary numeric promotion is applied to the char, giving int as a result. So the code becomes effectively:
System.out.println(start + +((int)'\t') + end);
which is effectively:
System.out.println(start + +(9) + end);
which is effectively
System.out.println(start + 9 + end);
... at which point it's hopefully clear why you're getting the output you are.
To avoid accidentally ending up treating a character as an integer, it's probably best to just use strings instead - at which point the code won't compile because there's no unary + operator for String:
System.out.println(start + +"\t" + end);
... gives:
Test.java:6: error: bad operand type String for unary operator '+'
The problem is not just with the + + in your code. But it's also with the fact that you are using char '\t' and not String "\t".
So when you use System.out.println("Hello" + '\t');, the \t is taken as a character literal and appended to the string as \t.
But when you use System.out.println("Hello" + + '\t');, it becomes effectively System.out.println("Hello" + (+ '\t'));. So it is treated as an int by java. You only assign + and - signs to ints, not chars.
Remember you can do int i = +2 or -2 or + +2.
And the ASCII value of \t is 9. Hence it gets appended to the string and get's printed as Hello9.
You're using the char \t and not the string "\t" with the + operator so it is using the ascii numeric value of 9 for tab
so
System.out.println("\n"+ +'\t');
is the same as
System.out.println("\n"+ (+9));
I don't think this is a problem with eclipse. It works the same way on console also. The +'\t' is considered as integer value 9 by Java not as a Character.

What happens if you remove the space between the + and ++ operators?

EDIT 1
DISCLAIMER: I know that +++ is not really an operator but the + and ++ operators without a space. I also know that there's no reason to use this; this question is just out of curiosity.
So, I'm interested to see if the space between + and ++var is required in Java.
Here is my test code:
int i = 0;
System.out.println(i);
i = i +++i;
System.out.println(i);
This prints out:
0
1
which works as I would expect, just as if there were a space between the first and second +.
Then, I tried it with string concatenation:
String s1 = "s " + ++i;
System.out.println(s1);
// String s2 = "s " +++i;
This prints out:
s 2
But if the third line is uncommented, the code does not compile, with the error:
Problem3.java:13: unexpected type
required: variable
found : value
String s2 = "s " +++i;
^
Problem3.java:13: operator + cannot be applied to <any>,int
String s2 = "s " +++i;
^
What's causing the difference in behavior between string concatenation and integer addition?
EDIT 2
As discussed in Abhijit's follow-up question, the rule that people have mentioned (the larger token ++ be parsed first, before the shorter token ++) is discussed in this presentation where it appears to be called the Munchy Munchy rule.
There is no +++ operator. What you have there is a postfix ++ operator followed by an infix + operator. That is a compilation error because postfix ++ can only be applied to a variable, and "s " isn't a variable.
Since you really mean an infix + operator followed by a prefix ++ operator, you need to put the space in between the operators.
Actually, you should do it ANYWAY. +++ is a crime against readability!!!
Compiler generates longest possible tokens when parsing source, so when it encounters +++, it takes it as ++ +.
So the code of
a +++ b
Will always be same as
(a++) + b
The triple plus is not an operator itself, it is two operators combined:
What the triple plus acutually does is:
a+++1 == a++ + 1;
What you are trying to do is ++ a String, which is undefined.
Never ever use +++ without spaces in your code; hardly anyone will know what it does (without consulting web). Moreover, after a week or so, you will not know what it actually does yourself.
+++ isn't an operator by itself.
i = i +++i; results in a pre-increment value of i, then adding it to the value of i and storing it in i.
With the String, + doesn't mean addition, so you're attempting to concatenate the string and the integer together.

Categories

Resources