Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to return a value from a lambda expression?

I have a collection (concurrentHashMap) and a method which should work in a separate thread and return numOfApples:

public int getApples(String treeNum) {
    int numOfApples = null;
    Runnable task = () -> {concurrentHashMap.get(treeNum).getApples(); };
    new Thread(task).start() ;
    return numOfApples;
}

Is it possible to pass num of apples from lambda expression (concurrentHashMap.get(treeNum).getApples()) to the numOfApples variable?

like image 513
May12 Avatar asked Dec 17 '15 10:12

May12


People also ask

How do you return a value from lambda?

Lambda functions are syntactically restricted to return a single expression. You can use them as an anonymous function inside other functions. The lambda functions do not need a return statement, they always return a single expression.

Can we return from lambda expression?

A return statement is not an expression in a lambda expression. We must enclose statements in braces ({}). However, we do not have to enclose a void method invocation in braces. The return type of a method in which lambda expression used in a return statement must be a functional interface.

Can lambda statements return a value?

A lambda function doesn't contain a return statement because it will have only a single expression which is always returned by default. You don't even have to assign a lambda either as it can be immediately invoked (see the next section).

What is return type of lambda expression?

What is the return type of lambda expression? Explanation: Lambda expression enables us to pass functionality as an argument to another method, such as what action should be taken when someone clicks a button. 4.


1 Answers

The problem is not about returning the value from a lambda expression. It is about returning a result from an asynchronous task.

You won't be able to do that easily using a Runnable. You should use a Callable instead, quoting its Javadoc:

A task that returns a result and may throw an exception.

Also, you definitely should not be creating unmanaged raw threads like that: new Thread(task).start();. You should use an ExecutorService and submit the Callable to it.

Consider the following code:

public int getApples(String treeNum) {
    Callable<Integer> task = () -> concurrentHashMap.get(treeNum).getApples();
    Future<Integer> future = Executors.newCachedThreadPool().submit(task);
    return future.get();
}

It creates a Callable<Integer> holding the task returning the number of apples. This task is submitted to an ExecutorService (I simply used a cached thread pool here, you might want another). The result is contained inside a Future<Integer> instance, whose get() method will block, wait for the result and then return it.

like image 100
Tunaki Avatar answered Oct 22 '22 19:10

Tunaki