2017-06-17 37 views
2

我想了解Java 8中的lambdas。我有一個使用功能接口的非常簡單的示例。使用java 8傳遞函數代碼供應商

這不是一個工作例子,我知道我可以直接調用method1method2,而不是使用getValue()Supplier,但是,我想知道是否有使用supplier.get()調用method1method2任何問題。

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運行。這是供應商的有效用途嗎?

+1

你的'mytest'沒有返回語句。它無法編譯。 –

+1

你能否澄清你的意思是「任何問題」?由於此問題目前已編寫,因此它似乎是一個基於意見的問題(對於此站點而言,這是[off-topic](http://stackoverflow.com/tour))。 –

+0

假設你要返回getValue,你使用的是泛型,但是所有的lambda只返回字符串。這隻會在T總是一個字符串時才起作用。 – Novaterata

回答

3

Supplier接口的優點之一是以懶惰的方式提供一個值。

我們儘量推遲一個supplier.get()調用,因爲在真正需要執行資源消耗操作時(如果有的話)會更好,以避免出現操作結果的情況可以忽略或可能被忽略。

在這裏,Supplier的包裝是沒有意義的,因爲沒有條件可能不會被調用。另外,我沒有看到爲什麼這些方法應該被懶惰地執行的任何理由。雖然,我也看不到一個完整的處理。

編輯:

如何在內部supplier工作?當創建supplier時,是否保留對foo()的引用以及傳遞給foo的參數?

想想一個lambda表達式,就像使用重寫單個方法的匿名類聲明的快捷方式(因爲它實際上是)。在lambda體中,您只需編寫將在被調用時執行的方法代碼。

不,它不保留引用,因爲它可以直接訪問它們(有些限制像有效的最終變量)。

+0

我已經更新了基於安德魯評論的問題。對於這個令人費解的例子感到抱歉。 – jakew