Java 中 lambda 的返回值
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/38540481/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Return value by lambda in Java
提问by Freeman
Till now I manage to find all answers I need but this one confusing me. Let's say we have example code:
直到现在我设法找到我需要的所有答案,但这个让我感到困惑。假设我们有示例代码:
public class Animal {
private String species;
private boolean canHop;
private boolean canSwim;
public Animal(String speciesName, boolean hopper, boolean swimmer) {
species = speciesName;
canHop = hopper;
canSwim = swimmer;
}
public boolean canHop() { return canHop; }
public boolean canSwim() { return canSwim; }
public String toString() { return species; }
}
public interface CheckAnimal {
public boolean test(Animal a);
}
public class FindSameAnimals {
private static void print(Animal animal, CheckAnimal trait) {
if(trait.test(animal)){
System.out.println(animal);
}
public static void main(String[] args) {
print(new Animal("fish", false, true), a -> a.canHop());
}
}
OCA Study Guide (Exam 1Z0-808) book says that these two lines are equivalent:
OCA Study Guide (Exam 1Z0-808) book 说这两行是等价的:
a -> a.canHop()
(Animal a) -> { return a.canHop(); }
Does this mean that, behind the scenes, Java adds keyword returnto code in the first case?
这是否意味着,在幕后,Java在第一种情况下为代码添加了关键字return?
If answer is YES then how next code compile (imagine everything else is in proper place):
如果答案是肯定的,那么接下来的代码是如何编译的(想象其他一切都在适当的位置):
static int counter = 0;
ExecutorService service = Executors.newSingleThreadExecutor();
service.execute(() -> counter++));
if we know that signatures for executeand Runnable's runare:
如果我们知道execute和 Runnable 的运行签名是:
void execute(Runnable command)
void run()
If answer is NO then how Java know when it need to return something and when not to? Maybe in
如果答案是否定的,那么 Java 怎么知道什么时候需要返回一些东西,什么时候不需要呢?也许在
a -> a.canHop()
case we wanted to ignore booleanreturn type of method.
如果我们想忽略方法的布尔返回类型。
采纳答案by Peter Lawrey
Does this mean that, behind the scenes, Java adds keyword return to code in the first case?
这是否意味着,在幕后,Java 在第一种情况下为代码添加了关键字 return?
No, The compiler generates byte code, and it might generate the same byte code but it doesn't change the syntax and then compile it again.
不,编译器生成字节码,它可能会生成相同的字节码,但不会更改语法,然后再次编译。
we wanted to ignore boolean return type of method.
我们想忽略布尔返回类型的方法。
It has the option of ignoring a value based on what functional interfaces it is considering.
它可以根据正在考虑的功能接口忽略某个值。
a -> a.canHop()
could be
可能
(Animal a) -> { return a.canHop(); }
or
或者
(Animal a) -> { a.canHop(); }
based on context, however it favours the first if possible.
基于上下文,但是如果可能的话,它倾向于第一个。
Consider ExecutorService.submit(Callable<T>)
and ExecutorService.submit(Runnable)
考虑ExecutorService.submit(Callable<T>)
和ExecutorService.submit(Runnable)
ExecutorService es = Executors.newSingleThreadExecutor();
es.execute(() -> counter++); // has to be Runnable
es.submit(() -> counter++); // Callable<Integer> or Runnable?
Saving the return type you can see it's a Callable<Integer>
保存返回类型你可以看到它是一个 Callable<Integer>
final Future<Integer> submit = es.submit(() -> counter++);
To try yourself, here is a longer example.
为了自己尝试,这里有一个更长的例子。
static int counter = 0;
public static void main(String[] args) throws ExecutionException, InterruptedException {
ExecutorService es = Executors.newSingleThreadExecutor();
// execute only takes Runnable
es.execute(() -> counter++);
// force the lambda to be Runnable
final Future<?> submit = es.submit((Runnable) () -> counter++);
System.out.println(submit.get());
// returns a value so it's a Callable<Integer>
final Future<Integer> submit2 = es.submit(() -> counter++);
System.out.println(submit2.get());
// returns nothing so it must be Runnable
final Future<?> submit3 = es.submit(() -> System.out.println("counter: " + counter));
System.out.println(submit3.get());
es.shutdown();
}
prints
印刷
null
2
counter: 3
null
The first submit
take a Runnable
so Future.get()
returns null
第一个submit
取一个Runnable
所以Future.get()
返回null
The second submit
defaults to being a Callable
so Future.get()
returns 2
第二个submit
默认为Callable
soFuture.get()
返回2
The third submit
can only be a void
return value so it must be a Runnable
so Future.get()
returns null
第三个submit
只能是一个void
返回值所以它必须是一个Runnable
所以Future.get()
返回null
回答by SamTebbs33
You are confused about the scope of the return
statement. The return
statement (whether inserted as bytecode by the compiler or as source code by the programmer) returns from the lambda, and not from the method that calls the lambda.
您对return
声明的范围感到困惑。该return
语句(无论是由编译器作为字节码插入还是由程序员作为源代码插入)从 lambda 返回,而不是从调用 lambda 的方法返回。
void foo() {
Supplier<String> s = () -> { return "bar" };
String s = s.get(); // s is assigned to "bar"
// Execution continues as the return statement in the lambda only returns from the lambda and not the enclosing method
System.out.println("This will print");
}
回答by Guillaume Poussel
Yes, when specifying only a single statement, its value is automatically returned from the lambda.
是的,当只指定一个语句时,它的值会自动从 lambda 返回。
Then, since Runnable
is a Functional Interface, it can be defined as a lambda. The return type is void
, so any return value inside the lambda will be ignored.
然后,由于Runnable
是函数式接口,因此可以将其定义为 lambda。返回类型是void
,因此 lambda 内的任何返回值都将被忽略。