我试图理解Java 8中的lambdas。我有一个使用功能接口的非常简单的示例。
这不是一个工作示例,我知道我可以直接调用method1
和method2
,而不是使用getValue()
和Supplier
,但是,我想知道使用supplier.get()
调用method1
和method2
是否存在任何问题。
public <T> T mytest(SomeObject var) {
//extract values from someobject
if(somecondition) {
getValue(() -> method2(obj5instance, obj6instance));
} else {
getValue(() -> method1("somestr", obj1instance, obj2instance, obj3instance));
}
}
private String method1(String s1, Obj1 s2, Obj2 s3, Obj3 s4){
//network call here to compute return value
return "computedmethod1";
}
private String method2(Obj5 s2, Obj6 s3){
//network call here to compute return value
return "computedmethod2";
}
public <T> T getValue(Supplier<T> supplier){
//this will call method1 or method2
//wrap the return value from supplier.get and return
return supplier.get();
}
根据安德鲁的评论进行更新。
这很有意义,谢谢。我很难理解供应商的概念。
C1.java
public C3 m1(Obj obj){
Supplier<String> mysupplier = () -> foo(arg1, arg2, arg3); //foo is an expensive call
return someFn(mysupplier);
}
供应商内部如何运作?创建供应商时,它是否保留对 foo() 的引用以及传递给 foo 的参数?
public C3 someFn(Supplier<String> supplier){
//this returns an instance of C3 that has a method lazyCall() which runs supplier.get()
}
C2.java
C3 c3 = c1.m1(obj);
如果调用 c3.lazyCall(),它将运行 supplier.get() 并运行 foo。这是对供应商的有效使用吗?
Supplier
接口的优点之一是以懒惰的方式提供值。
我们尝试尽可能延迟supplier.get()
调用,因为最好在确实需要执行资源消耗操作(如果有的话)时执行该操作,避免可以忽略或可能跳过操作结果的情况。
在这里,Supplier
上的包装器是没有意义的,因为没有任何条件可以不调用它。另外,我看不出应该懒惰地执行这些方法的任何理由。不过,我也没有看到完整的处理过程。
编辑:
supplier
内部如何工作?创建supplier
时,它是否保留对foo()
的引用以及传递给 foo 的参数?
将 lambda 表达式视为覆盖单个方法的匿名类声明(实际上是)的快捷方式。在 lambda 主体中,您只需编写方法代码,该代码将在调用时执行。
不,它不保留引用,因为它可以直接访问它们(有一些限制,例如有效的最终变量)。