user3692741
user3692741

Reputation:

How can I ensure that a method returns a value?

The method I have written below is supposed to act on a BinaryTreeNode to flatten the tree 'beneath' that node. My if-else if-else together with a recursive (?) structure, to my understanding, will always return a value, but I am getting an error in Eclipse saying "This method must return a result of type <Integer>.

After doing research, I believe that Java cannot quite tell that the method will always return a correct value, since the return statement is in an 'else'. Is this the problem? How can I alternatively design the method to avoid this problem?

//doFlatten acts on a BinaryTreeNode and takes a storage list as an argument
//it will call itself on any children on the node
//if the node is a leaf, it will update the storage list and return that updated list
public List<Integer> doFlatten(List<Integer> result){
    if (this.leftChild != null){
        this.leftChild.doFlatten(result);
    }
    else if (this.rightChild != null){
        this.rightChild.doFlatten(result);
    }
    else{
        result.add(this.value); //add leaf to result list
        return result;
    }
}

Upvotes: 0

Views: 258

Answers (5)

Amir Afghani
Amir Afghani

Reputation: 38541

I think you just want :

//doFlatten acts on a BinaryTreeNode and takes a storage list as an argument
//it will call itself on any children on the node
//if the node is a leaf, it will update the storage list and return that updated list
public List<Integer> doFlatten(List<Integer> result){
    if (this.leftChild != null){
        return this.leftChild.doFlatten(result);
    }
    else if (this.rightChild != null){
        return this.rightChild.doFlatten(result);
    }
    else{
        result.add(this.value); //add leaf to result list
        return result;
    }
}

Notice that in my version, all predicate outcomes lead to a List<Integer> being returned, where in your case, only the else clause does.

Upvotes: 0

AlexR
AlexR

Reputation: 115378

Examine your code again. You have only one return statement in the last else branch. This means that your method returns value only if it arrives to this point. This is exactly what compiler reports you.

So, the question "how to ensure that my method returns value" can be answered like "compile your code". If you managed to compile code be sure that your method indeed returns value or throws exception.

If however you are actually asking about the best coding practices that help you to avoid such compilation errors IMHO there is no one 100% correct answer.

See the recommendations of Luigi Mendoza. In some cases they are good. However (sorry, Luigi) I cannot agree that they always good. I'd say that you should avoid if/else structures when it is possible. For example series of if statements with return in the end of if block in some cases more readable.

Upvotes: 0

Loedolff
Loedolff

Reputation: 172

Make the return type void and remove return result. There's no need to return the result object, since it's the same result object that was passed in (the caller already has a reference to it).

Upvotes: 2

Daniel Sperry
Daniel Sperry

Reputation: 4491

Your method actually doesn't always return a value (the first if and first else) don't have a return.

This seems to be what you want:

    public List<Integer> doFlatten(List<Integer> result){
        if (this.leftChild != null){
            this.leftChild.doFlatten(result);
        }
        else if (this.rightChild != null){
            this.rightChild.doFlatten(result);
        }
        else{
            result.add(this.value); //add leaf to result list
        }
        return result;
    }

Upvotes: 0

Luiggi Mendoza
Luiggi Mendoza

Reputation: 85779

The best bet is to define the a variable with the return type of the method and initialize it a default value, assign the proper value of the result in the method, and in the end, as the last line of the method, return this variable.

For your method, it may look like this:

public List<Integer> doFlatten(List<Integer> result) {
    List<Integer> realResult = new ArrayList<>(result);
    if (this.leftChild != null){
        this.leftChild.doFlatten(result);
    }
    else if (this.rightChild != null){
        this.rightChild.doFlatten(result);
    }
    else{
        result.add(this.value); //add leaf to result list
        realResult.add(this.value);
        //avoid return statement here
        //return result;
    }
    //single point for return statement
    return realResult;
}

But, for this case, as you can see in code above, it seems meaningless to even return a result because the proper result of this method is stored in List<Integer> result. So, just make your method void:

public void doFlatten(List<Integer> result) {
    //rest of your code...
}

Upvotes: 0

Related Questions