Java: Difference between +--i and +++i - java

Last day while programming, I mistakenly wrote something like this-
int i = 2;
int j = 3;
int a = i+++j;
And it did not shoot any error and I got-
a = 5
After detecting this coding error I was curious. So, I started playing with it. When I changed it a little-
int a = i+ ++j;
I got-
a = 6
With this-
int a = i+ + +j;
and this-
int a = i++ +j;
I again got-
a = 5
Similar situation was experienced here.
But here comes the weird part. There is no difference between a = i+--j & a = i+ --j. Both gives-
a = 4
Why is that? I completely understand what exactly is happening here. The thing I do not understand is- 'WHY?'. + and - are both operators, then why there is a difference?
For clarity, I wish to share another odd experience. This code works perfectly-
int i=0;
System.out.println("value: "+--i);
And outputs-
value: -1
But this-
System.out.println("value: "+++i);
Gives following error-
error: unexpected type

As #Bunti pointed out, your answer is in the Operator Precedence.
When you do,
int a = i+++j;
It's evaluated as int a = (i++) + j since Postfix has the highest precedence.
Now you know why you get a = 5 there. Print i along with a and you will see it's incremented.
Similarly, when you do System.out.println("value: "+++i);, it's evaluated to System.out.println(("value: "++) + i);
But postfix operations are not applicable to String. Hence the syntax error.
But when you do, System.out.println("value: "+--i);, this is evaluated to System.out.println("value: "+ (--i));. Hence it works just fine.

Operator precedence is only half of the answer, since the first thing to clarify is what the operators in your code are.
Basically i+++j could be interpreted as i ++ + j, as i + ++ j or as i + + + j.
However according to the lexical rules of Java (https://docs.oracle.com/javase/specs/jls/se7/html/jls-3.html#jls-3.2) the interpretation is the same as if the expression was written as i ++ + j.
According to the operator precedence this is evaluated is (i++) + j, so that in int a = i++ + j; a is 5 (and i is 3!).
For i+--j the tokens are i + -- j (since the is no operator +-), which is according to operator precedence i + (--j), so that in int a = i + --j; a is 4 (and j is now 2).
Now comes the fun part:
What is int a = i + + + j;? This is the same as int a = i + (+(+j)); (+j being the unary plus operation on j), so this gives again 5 (but i is still 2 and j is still 3, which is different from the case i++ + j!)
And what is int a = i + - - j;? This is the same as int a = i + (-(-j)); (-j being the unary minus operation on j) which also gives 5 (and also does not modify i or j).
What is int a = i++++j;? This is not a valid Java expression (it will not compile), since this is equivalent to (i++) ++ j and since i++ cannot be converted to a variable this is illegal (https://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.14.2) and then there is this dangling j too.
Adding more + without adding spaces does not make it legal, while i++ + ++j is perfectly legal...
Similarly, "SomeString"+++i is illegal, since this is read as ("SomeString"++)+i and you can't increment a String literal (and also not a String variable).
"SomeString"+--i is valid, since this is read as "SomeString"+(--i), which appends the result of --i to "SomeString".

Many of them have written answers for this. I would like to put it in different words.
i++ is post fix.
In post fix operation, value is incremented after the value is extracted.
Thus in case of i+++j, we have original value of i when expression is evaluated, and i is incremented after the evaluation is completed.
In case of ++j since its prefix value is incremented before evaluation.
This i+++j is equal to (i++)+j and i+ ++j is equivalent to i + (++j).
Hope this adds this helps adding to your understanding.

Hope this answers the behavior of arithmetic operation-
int i = 2;
int j = 3;
int a = i+++j;
a=5 as there is no space between the + symbol. Even if you put any more + symbols in between, the answer will remain the same. To explain its working, it is similar to any basic calculator we use, if i input a number and type + for any number of times, the second input when received will still give the sum of the 2 input-ed numbers. This is because the compiler is initializing the addition operation between the 2 numbers.
int a = i+ ++j;
Here in this case, you are adding the i to the incremented value of j. So it is like u are looking for an operation of 2+ ++3, which is 2+4 and hence the answer 6. the ++ operator is defined as an increment in the JRE.
int a = i+ + +j;
Here it behaves same as the 1st case as +j or i+ are not increment operators defined by JRE.
int a = i+--j;
In this interesting case, we are using 2 diff arithmetic operators i.e. + and --. As -- is defined, the decrement of j value happens and the change value of j is added to i.
int a = i+ --j;
As in above, since + and - are diff operations. the space between them or not doesn't matter.
int i=0;
System.out.println("value: "+--i);
In this case, we are printing a string and using +--i; so JRE treats it as printing out Value: decrement of i. As known in print statement, + is used to make system print multiple value at a time.
System.out.println("value: "+++i);
coming to this, the + in print function is defined to provide a way to print several variable that are separated by a + symbol and hence the conjunction of +++ is not defined for print function and hence gives an error.

May be the i+++j just is i+j, but the i+ ++j is i + ++j, there ++j change's , 'j=4'. So i[2] + j[4] = 6.
Java May not recognize three +++.

Related

Why does jshell show this number?

I am learning java and this logic makes me feel confused.
Isn't here i=20(+1)+20(+1)?
Why 41 instead of 42?
jshell> int i = 20
i ==> 20
jshell> i=i++ + i++
i ==> 41
See this code run at Ideone.com.
Effectively, the expression i=i++ + i++; is equal to i=i++ + i;. Why? The latter i++ result value is never used and is not propagated. The result of the postfix addition i++ is used as long as the value i is added later in the expression and the result takes the effect. However, after the latter i++ the result value of i is not used.
If you want to achieve the result of 42, you need to perform the postfix assignment (i++) after the whole result is assigned back to the i variable:
int i = 20;
i = i++ + i;
i++;
System.out.println(i);

Is it possible to add integer values while concatenating Strings? [duplicate]

This question already has answers here:
concatenating string and numbers Java
(7 answers)
Closed 1 year ago.
Consider the following code (excerpt of main method):
String str = "The result: ";
int c = 5;
int k = 3;
System.out.println(str + c + k); // This would concatenate the all values, i.e. "The result: 53"
If the only thing allowed to be modified is within System.out.println(), is it possible to concatenate str to the sum of k and c?
Yes.
System.out.println(str + (c + k));
You can change order of execution by adding parentheses (same way as in math).
Indeed, as #talex said, you may use this single line code.
Yet, I think that this additude is a bit confusing, and may cause the code to be unreadable.
A better practice would be:
String str = "The result: ";
int c = 5;
int k = 3;
int result = c + k;
System.out.println(str + result);
This way, the code is more readable, and the order of execution will not confuse the programmers that read this code.
Yes
you should have use parentheses around sum of integers
System.out.println(str + (c + k));

Strings and Loops Practice Test

I'm slightly confused on this test question. I made a chart of the values of i , j, and the string. I got "nbearig", but my runtime is printing out numbers. I'm not sure where I went wrong. ++i , --j means that they were incre/decremented before the code after the for loop right?
public class AlGore {
public static void main(String[] args) {
String mystery = "mnerigpaba";
String solved = "";
int len = mystery.length();
for (int i = 0, j = len - 1; i < len/2; ++i, --j) {
solved += mystery.charAt(i) + mystery.charAt(j);
}
System.out.println(solved);
}
}
I'm not sure where I went wrong. ++i , --j means that they were incre/decremented before the code after the for loop right?
1) They were preincremented / predecremented respectively.
2) It happened after each execution of the loop body.
my compiler is printing out numbers.
No it isn't. The compiler is compiling your code!!! The JVM is printing numbers ... when you run the code.
To understand the reason why, take a careful look at this:
solved += mystery.charAt(i) + mystery.charAt(j);
This is equivalent to
solved = solved + ( mystery.charAt(i) + mystery.charAt(j) );
Now the expression in brackets performs a numeric addition of a character to a character. According to the rules of Java expressions, that gives an int value. So the entire expression becomes:
solved = String.concat(
solved,
Integer.toString(mystery.charAt(i) + mystery.charAt(j));
I thought that the charAt(i) function will return a string?
No. It returns a char ... just like the method name "charAt" implies. String and char are fundamentally different types.
Comment: That is a good exam question, it tests how well you understand loops, and how well you understand Java expression semantics.
You are performing integer math (because char is an integral type),
// solved += mystery.charAt(i) + mystery.charAt(j);
solved += Character.toString(mystery.charAt(i))
+ Character.toString(mystery.charAt(j));
That way you are performing String concatenation.
mystery.charAt(i) + mystery.charAt(j); will add the numeric values of those two characters. You can force string concatenation by adding "" + before:
solved += "" + mystery.charAt(i) + mystery.charAt(j);

Java String += Shorthand explanation needed

While I was creating a program to compress a string I ran into this strange problem, I will paste the code snippets with their outputs, I would like someone to clearly explain why this is happening.
The first code snippet: here if same letter appears consecutively, then the successive occurrences of the letter is replaced by the total count of same letters. Ex: aaabbb should be written as a3b3.
public static String compress(String str){
String compressed = "";
char prev = str.charAt(0);
int count = 1;
for (int i = 1; i < str.length(); i++) {
char curr = str.charAt(i);
if (curr == prev) { // in case curr is equal to prev
count++;
} else { // in case curr is not equal to prev
//compressed=compressed+prev+count;
compressed+=prev+count; // Shorthand used here
count=1;
prev=curr;
}
}
compressed=compressed+prev+count; // Shorthand not used
System.out.println(compressed);
return compressed;
}
the output for this above code when inputted with aabbccaabbccaabbccaabb is 99100101991001019910010199b2, observe the last two elements of the output, this is because outside the loop, shorthand is not used. If I write the expression as compressed = compressed +prev+count inside the loop, I'll get the intended output.
I thought this output is because the operation is messing with the address of the String. But the next code confused me again.
String prev= "abc";
String curr = "def";
String result="";
result+=prev+curr;
System.out.println(result);
I think this is because the right hand operation is performing an ASCII addition, I cannot come to a conclusion, can anyone clarify.
I am sleep deprived and hence I am not able to come to a conclusion, hence asking someone to clarify my trivial doubt.
It has nothing to do with the reference. When you did prev+count ascii value of the character in prev is added with the integer count. In this case :
ascii of "a" is 97, and it occurred twice... so 97 +2 = 99 ..
ascii of "b" is 98, and it occurred twice... so 98 +2 = 100 ..
ascii of "c" is 99, and it occurred twice... so 99 +2 = 101 ..
that's why the output is 99100101991001019910010199100
try this : compressed+=(""+prev)+count; // Shorthand used here
In this case, or in compressed+=""+prev+count case, since the operation happens from left to right, the + operator is applied on a string ("") and char(prev) and behaves like append and also returns a string. The resulting string is then appened with another int (prev)
A better way is using a StringBuilder
Take a look at this subject and at JLS 15.18.1 section :
You see this behavior as a result of the combination of operator
precedence and string conversion.
JLS 15.18.1 states:
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.
Therefore the right hand operands in your first expression are
implicitly converted to string: string = string + ((char)65) + 5;
For the second expression however string += ((char)65) + 5; the +=
compound assignment operator has to be considered along with +.
Since += is weaker than +, the + operator is evaluated first.
There we have a char and an int which results in a binary numeric
promotion to int. Only then += is evaluated, but at this time
the result of the expression involving the + operator has already been evaluated.
Whenever you add a char to an int in java first it converts the character into its equivalent ASCII value and then adds it to the integer
eg suppose the following scenario ,
char c = 'a'; // ASCII value of 'a' is 97
int i = c + 5 ; // result will be 97 + 5 = 102
I think this answers your first half question
Now the Second part ,
Whenever you use the shorthand operator in Java the expression at right hand side is evaluated first.
Hence , for expresion
result += prev + curr it is evaluated as
result = result + (prev + curr);
Therefore ,
result+=prev+curr; // Here first it appends "abc" with "def" and then the resultant "abcdef" is appended to as result .
you can convert your charater value "prev" to string and than append count to it.
compressed += Character.toString(prev) + count;

How to display an array of integers in a JTextArea?

for (int j =0; j < marks.size(); j++) {
analyzeTextArea.setText(j + marks.get(j));
}
The above code gives me the following error:
required: java.lang.String found: int
I guess marks.get(j) give you an Integer. So when you do j + marks.get(j) you add the value of marks.get(j) to the value of j.
So you end with an Integer as result of j + marks.get(j). But setText expect a String.
You have several possibilities now depending on you needs.
analyzeTextArea.setText(Integer.toString(j + marks.get(j)));
This case still make the addition then convert it to String in order to respect setText parameter type.
With this :
analyzeTextArea.setText("" + (j + marks.get(j)));
"" tells that the parameter will be a String and then you will concatenate j and marks.get(j). So, for example, for the first loop you will have something that start with 0
Now using setText in a loop don't really make sense because only the last value set in the loop will be used you probably should use JTextArea#append(String).
You need to do something like this:
analyzeTextArea.setText("" + (j + marks.get(j)));
analyzeTextArea.setText(Integer.toString(j + marks.get(j)));
Try this,
for (int j =0; j < marks.size(); j++) {
analyzeTextArea.setText(j + marks.get(j)+"");
}
That should work but instead of .setText(), you should use .append(). because .setText() deletes the previous contents and writes it. but .append() just adds on information

Categories