Class value is not affected by method - java

I am following the U of Helsinki's Java course and I have difficulty on example 75.1.
link
The problem is that my method doesn't affect the object's value. For example, the exercise requires an output of
value: 10
value: 9
value 8
However, I receive:
value: 10
9
value: 10
9
value: 10.
The code I use is:
public void decrease() {
System.out.println(this.value - 1);
Additionally, I cannot use a return statement as the method must be void.

Right. Generally speaking, "print x - 1" does not change the value of x. So, we must change this.value. We do so through assignment:
public void decrease() {
this.value = this.value - 1; // decrease the value
System.out.println(this.value); // print the new value
}
We can actually do this with a single line with the unary -- operator:
public void decrease() {
System.out.println(--this.value); // Decrease this.value first,
// then print the new value
}
Notice the placement of --. If we write --this.value, we decrease and then print. If we write this.value--, we print then decrease.

You can print then decrement the value:
System.out.println(this.value--);

Just decrement the value. The caller seems to take care of printing (by calling printValue)
public void decrease() {
this.value--;
}

Merely invoking this.value - 1 does not change the value of value. If you want to actually change the value, you have two choices:
Use a decrement statement (value--), or
Reassign the variable (which is long-hand for the decrement).
value = value - 1

Never mind, I've got it.
code needed to be:
this.value = this.value - 1;

System.out.println(this.value - 1);
Will only print the value -1 there is no assignment.
You need something like
System.out.println(this.value = this.value -1);
or
System.out.println(this.value -= 1);

Related

If code structure

I know basic if statement structure, but this confuses me
public void setHandleName(String handle){
if(handle.length() < 10){
return;
}
handleName = handle;
}
It returns the value when the handle.length() is bigger than 10, isn't it supposed to be returning the value when handle.length() is less than 10?
Why does this if statement does the opposite?
if(false){ //do stuff; }
Where the if statement should be
if(true){ //do stuff; }
Sorry for the vague explanation, english is not my native language.
Any help will be appreciated!
Thanks!
It returns the value when the handle.length() is bigger than 10
No it doesn't. It never returns any value, the method is of type void. It does set the handleName instance field if the name is at least 10 characters long (and not set it if the name is less than 10 characters long).
, isn't it supposed to be returning the value when handle.length() is less than 10?
No, the if clearly says "If the length of handle is less than 10, return" and that's before it sets handleName. return leaves the function right away, bypassing any code that may follow.
Why does this if statement does the opposite?
if(false){ //do stuff; }
Because in that case, the logic is within the if block; in your first example, it's after an if block that returns early (bypassing the remainder of the function). That is, your first example is:
if (!condition) {
return;
}
doSomething();
but your second example is
if (condition) {
doSomething();
}
Here's an annotated version of your first example:
public void setHandleName(String handle){ // Accept a `handle` string parameter
if(handle.length() < 10){ // If the length of `handle` is less
// than 10, enter the block
return; // Leave this method immediately, without
// doing anything else
} // This is the end of the conditional bit
handleName = handle; // Set `handleName` to `handle`
}
So if we go into the if block, we'll return, and never reach the handleName = handle; line, so we never set it. If we don't go into the if block, we don't return early, so we do set it.
We can (and probably should) rewrite setHandleName to use the structure from your later examples:
public void setHandleName(String handle){ // Accept a `handle` string parameter
if(handle.length() >= 10){ // If `handle`'s length is 10 or higher
handleName = handle; // Set `handleName` to `handle`
} // This is the end of the conditional bit
}
It doesn't return anything (as the void return type indicates). It sets the value of handleName to handle, but only if handle.length() is greater or equal to 10. If handle.length() is less than 10 it will just return from the method without doing anything more.
There are a few things to note:
The return type on this method is void. This means that it doesn't have a value to return. You can absolutely use return in a void method, but that implies...
This method returns early based on a condition. Effectively, if the value doesn't satisfy a specific criteria, it silently ignores what was passed into it.
Does this make it clearer what the code is actually doing?
public void setHandleName(String handle){
if(handle.length() >= 10){
handleName = handle;
}
// otherwise handleName is not set, and the method exits
// nothing is returned because the method is 'void'
}
Please note that if(false){ //do stuff; } will never "do stuff"

Recursive return error, Java

So I'm defining a recursive function that takes as an argument a value for x (like the arithmetic variable x, i.e. "x + 3 = 5") and returns the result of the arithmetic expression. The expression is taken from a Binary expression tree that looks like this:
You start at the root and keep working your way down till you hit the leaves, and once you do you come back up. The expression on the tree is then:
x * ( (x + 2) + cos(x-4) ).
My code for this function is as follows:
// Returns the value of the expression rooted at a given node
// when x has a certain value
double evaluate(double x) {
if (this.isLeaf()) {
//convert every instance of 'x' to the specified value
if (this.value.equals("x")) {
this.value = Double.toString(x);
}
//return the string-converted-to-double
return Double.parseDouble(this.value);
}
//if-else statements to work as the arithmetic operations from the tree. Checks the given node and performs the required operation
else {
if(this.value.equals("sin")) { return Math.sin(evaluate(Double.parseDouble(this.leftChild.value))); }
if(this.value.equals("cos")) { return Math.cos(evaluate(Double.parseDouble(this.leftChild.value))); }
if(this.value.equals("exp")) { return Math.pow(evaluate(Double.parseDouble(this.leftChild.value)), evaluate(Double.parseDouble(this.rightChild.value))); }
if(this.value.equals("*")) { return evaluate(Double.parseDouble(this.leftChild.value)) * evaluate(Double.parseDouble(this.rightChild.value)); }
if(this.value.equals("/")) { return evaluate(Double.parseDouble(this.leftChild.value)) / evaluate(Double.parseDouble(this.rightChild.value)); }
if(this.value.equals("+")) { return evaluate(Double.parseDouble(this.leftChild.value)) + evaluate(Double.parseDouble(this.rightChild.value)); }
if(this.value.equals("-")) { return evaluate(Double.parseDouble(this.leftChild.value)) - evaluate(Double.parseDouble(this.rightChild.value)); }
}
}
However the compiler is tossing an error telling me that my function must return a type double. Both the if and the else statements return a double- the if statement directly and the else statement through the sum of 2 doubles returned by the same function. What is the deal here? If I place a return statement outside of the if-else then the error resolves itself but to work with that would require me to keep a static or a global variable consistent through each recursion. I'd like to know what is wrong with my function as is, because it feels much more intuitive than a global variable and I think I'm missing a key concept about recursion here. Any help is appreciated- thank you!
Both the if and the else statements return a double
They actually don't. The if branch always does, but the else branch doesn't. What happens if this.value equals "Invalid", or something else which isn't in your list? Then it won't ever hit a return statement. Since it's required to always return, or throw an exception, this isn't allowed.
Even if you have your program structured in such a way that it logically always has to return a value, the compiler isn't going to be doing complex analysis on all the branches of your program to ensure that it always returns something. It just checks that each branch has a valid return.
So, for example, something like is invalid
if(x < 0) return -1;
if(x >= 0) return 1;
Because the compiler doesn't know that it always has to hit one of those two conditions (an issue which is further complicated by the fact that, depending on what x is, it might not always have to go down one of those branches).
Instead, your code should be structured like this:
if(x < 0) return -1;
else return 1;
So that every branch has a valid exit condition.

Why cannot I increment returned value?

I noticed surprising behaviour.
I can write so:
Integer integer = 0;
integer++;
But I cannot write so:
getInteger()++;
Here's my getInteger() method:
public static Integer getInteger(){
return 0;
}
For me two snippets look the same.
But the second piece of code returns an error:
unexpected type
getInteger()++;
^
required: variable
found: value
Why is the second construction forbidden?
Often, I feel forced to write "ugly" code like this:
obj.set(obj.get()+1);
It looks redundant.
x++ is not the same as x + 1. It's short for x += 1, i.e. x = x + 1; increment, then assign. So getInteger()++ means getInteger() = getInteger() + 1, which makes no sense. You're adding one to a value, not incrementing a variable.
Apart from that, ++ works on int but not Integer, but even if you were returning an int you couldn't increment it with ++:
class Test {
static public void main() {
getint()++;
}
static int getint() {
int a = 0;
return a;
}
}
gives
Test.java:3: error: unexpected type
getint()++;
^
required: variable
found: value
(In C++ you could make this work with references, but Java doesn't have those.)
8++ will not make sense,while
int x=8;
x++;
do make sense
because x++, is working like x+=1, i.e x=x+1
and 8=8+1 is something not acceptable.
As it says, it requires a variable for ++ operator. ++ increments a value that is stored somewhere, so the incremented value is now stored in that location. your function just returns a value , which is not a variable.
It's as simple as Rahul mentioned in the comment.
//This works
x=5;
x++; //Now x=6 since x++ is equivalent to x=x+1;
//This doesn't work
5++; //this doesn't even make sense, trying to do 5=5+1??
//similarly, getNumber() is just a value that is returned, it is a value, not a variable
//So it is like the second case
//This doesn't work
getNumber()++; //Trying to do getNumber()=getNumber()+1; ??
Why second constructions is forbid?
Integer is immutable, so you couldn't change it anyway. int is mutable but since it only returns a copy on the value, this won't work either.
e.g.
public static Integer getInteger(){
return 0;
}
// what would this do
getInteger()++;
// now the method has been changed to
public static Integer getInteger(){
return 0+1;
}
// so now
System.out.println(getInteger()); // prints 1 ??
obj.set(obj.get()+1);
This breaks encapsulation as well. I would suggest a method like this
AtomicInteger i = new AtomicInteger(0);
i.incrementAndGet();
or you could have your own
i.incr();
You are not returning an int, you're returning an Integer object. The Integer class is immutable and has no ++ operator of its own.
Also, the ++ operator requires that its operand be an lvalue, i.e. an assignable variable as opposed to a value. The result of getInteger() is the latter.
In the case of your first test:
Integer integer = 0; integer++;
Java's autoboxing allows the use of the ++ operator, but only because Java automatically converts the Integer into an int and then back again, and because the variable integer is an lvalue. It's more or less equivalent to:
int tmp_int = integer.intValue();
int result = tmp_int++;
integer = Integer.getInteger(tmp_int);
(void)result;
result - the effective "value" of the expression isn't integer because you've used the "post increment" version of ++, so the result is the value that integer had before it was incremented.

Why is increment on returned value on righthand side of return statement not evaluated? [duplicate]

This question already has answers here:
What is x after "x = x++"?
(18 answers)
Closed 8 years ago.
I'd like to know why a postfix increment on a value being returned in a return statement is not evaluated if the increment occurs on the righthand side of the return statement.
I know that the value returned should be the pre-increment value, but assuming a class-level variable, the increment should still show up in the variable itself.
Here is my example.
public class ReturnDemo {
static int val=1;
public static void main(String[] args)
{
System.out.println(getVal());
System.out.println(val);
}
public static int getVal()
{
return(val=(val++));
}
}
I would have expected this to print out
1
2
but it actually printed out
1
1
If you do the same thing without the assign, it increments correctly.
This, for example:
public class ReturnDemo {
static int val=1;
public static void main(String[] args)
{
System.out.println(getVal());
System.out.println(val);
}
public static int getVal()
{
return(val++);
}
}
Returns
1
2
(It gets val at 1 then increments the variable val to 2.)
Why is it that there is a line drawn in the sand at evaluating the postfix increment within a return statement if it's on the righthand side of an assignment, but that same line is not applied to postfix increments that are not part of an assignment statement?
The return is a red herring. The problem is val=(val++), which is Just Plain Ugly and Bad Practice.
val++ is post-increment. In other words, this subexpression returns the previous value of val, then increments the variable.
So you are telling the compiler you want to obtain the previous value of val (1), then increment it (2), then assign that previous value to val -- setting it back to 1 again. The program is doing exactly what you told it to do.
You're trying too hard. If you want to return the value of val after it has been incremented, you can use return ++val;. If you want to increment val but return the previous value, use return val++;.

Calculate the power of 2, java

I want to calculate the power of 2 using recursion. Here is my code:
class Aufg1{
public static void main(String args[]){
int erg = zweiHochPositiv(10);
}
public static int zweiHochPositiv(int exponent){
if(exponent > 0)
return (2*zweiHochPositiv(exponent--));
else
return 1;
}
}
I get a lot of errors at
return (2*zweiHochPositiv(exponent--));
but I have no idea what may be wrong.
Replace
return (2*zweiHochPositiv(exponent--));
with
return (2*zweiHochPositiv(exponent - 1));
exponent-- evaluates to the value of the exponent variable and then decrements it. So when you call zweiHochPositiv(1), the method will call zweiHochPositiv(1) again.
As a result, this method, when called with a value > 0, will recurse indefinitely and ultimately overflow the stack.
You need to use prefix version of --.
This should work:
return (2*zweiHochPositiv(--exponent));
Explanation: exponent-- will never actually lower exponent's value, so you're calling your recursive function every time with the same value, and that will blow your stack.
--exponent will lower it's value by one, so you should get desired behaviour.
I think an efficient way of doing it would be to use the binary representation property of a "power of 2" - its just a bit shift of 1, "exponent" number of times.
Hence, 2^2 = 1 << 2 = (in binary) ....0000 0100 = 4
return (2*zweiHochPositiv(--exponent));

Categories

Resources