2017-05-18 30 views
-2

我能得到這個與拉姆達的返回void並使用哈希表的同時在0 ARGS工作,看到這裏 - >Create lambda two dimensional array初始化Lambda表達式Runnable的陣列(串ARG並返回boolean)和呼叫指數

現在,我正試圖創建一個Runnable[]數組,並在索引中使用lambda,並且每個lambda使用一個String參數並返回一個布爾值。

這裏是代碼...

public class testLambdaWithPrimitiveType { 
    private final String[] numArray = {"One", "Two", "Three"}; 
    private boolean numFound = false; 

    testLambdaWithPrimitiveType(String num){ 
     setNumFound(num); 
    } 

    private void setNumFound(String num){ 
     Runnable[] runnableNumArray = { 
       () -> isStringOne(num), 
       () -> isStringTwo(num), 
       () -> isStringThree(num) 
     }; 

     for (int numChecked = 0; numChecked < runnableNumArray.length; numChecked++){ 
      if (runnableNumArray[numChecked].run(num)){ 
       this.numFound = true; 
      } 
     } 
    } 

    private boolean isNumFound(){return this.numFound;} 

    private boolean isStringOne(String num){ 
     return num.equals(numArray[0]); 
    } 

    private boolean isStringTwo(String num){ 
     return num.equals(numArray[1]); 
    } 

    private boolean isStringThree(String num){ 
     return num.equals(numArray[2]); 
    } 

    public static void main(String[] args) { 
     testLambdaWithPrimitiveType objectOne = new testLambdaWithPrimitiveType("One"); 
     testLambdaWithPrimitiveType objectTwo = new testLambdaWithPrimitiveType("Two"); 
     testLambdaWithPrimitiveType objectThree = new testLambdaWithPrimitiveType("Three"); 
     testLambdaWithPrimitiveType objectFour = new testLambdaWithPrimitiveType("Four"); 

     System.out.println(objectFour.isNumFound()); // false 
     System.out.println(objectThree.isNumFound()); // true 
     System.out.println(objectTwo.isNumFound()); // true 
     System.out.println(objectOne.isNumFound()); // true 
    } 
} 

它看起來像數組被正確初始化,但是當我嘗試對指數if (runnableNumArray[numChecked].run(num)){打電話,我得到一個編譯錯誤。任何想法爲什麼發生這種情況?

回答

1

這是因爲Runnable有方法void run(),不帶參數,而你試圖調用run(num)。由於參數setNumFound()已應用num,請使用run()撥打電話。

當然,這會導致第二個錯誤,即方法返回void,所以if (run())不起作用。

看來你可能想的方法boolean xxx(String),所以用Predicate<String>取代Runnable,你可以使用test(num)代替run()調用它。

然後導致編譯錯誤Cannot create a generic array of Predicate<String>,所以你必須用List替換數組。

然後,您可以改用方法引用。

private void setNumFound(String num){ 
    List<Predicate<String>> runnableNumList = Arrays.asList(
      this::isStringOne, 
      this::isStringTwo, 
      this::isStringThree 
    ); 

    for (Predicate<String> runnableNum : runnableNumList){ 
     if (runnableNum.test(num)){ 
      this.numFound = true; 
     } 
    } 
} 
+0

完美這正是我正在尋找。不知道謂詞庫。謝謝你:) –

+0

在我真正的應用程序中,我必須堅持for循環(因爲索引號會告訴我下一個需要執行的Runnable數組在哪裏),但是知道如何使用for-每個循環也是如此:) –

+0

'predicate'是一個返回'boolean'的方法。 'java.util.function'包有一組謂詞接口,用於常用參數:'謂詞'(一個對象參數),'IntPredicate'('int'參數),'LongPredicate'('long'參數), 'DoublePredicate'('double'參數)和'BiPredicate'(兩個對象參數)。對於任何其他類型的參數,您必須編寫自己的界面。 – Andreas

1

在Java語言中,Runnable實例不能有參數,而具有參數的lambdas實際上是Callable實例。換句話說,你的問題是不準確的......即使編譯器(錯誤地)允許你也不能創建帶有參數的Runnable數組。

的錯誤是Runnable接口與簽名run方法,

public abstract void run()

然而,你試圖傳遞參數給run方法。

runnableNumArray[numChecked].run(num)

卸下num參數仍將給你一個錯誤。這是因爲運行方法返回void這是什麼也沒有(再次看簽名)但if語句需要boolean值來評估。

我不確定你想用這個lambda表達式來實現什麼。如果你給我更多的信息,我可能會糾正你的代碼。儘管如此,目前還不清楚你期待Runnables的實現。

以下是使用Callable實例來實現您想要的內容的示例。

private void setNumFound(String num) throws Exception { 
    Callable[] runnableNumArray = { 
    () -> isStringOne(num), 
    () -> isStringTwo(num), 
    () -> isStringThree(num) 
    }; 

    for (int numChecked = 0; numChecked < runnableNumArray.length; numChecked++){ 
    if ((Boolean) runnableNumArray[numChecked].call()){ 
     this.numFound = true; 
    } 
    } 
} 
+0

我試圖避免使用'if/else if'語句的長鏈。在我真正的應用程序中,我想到如果我可以設置兩個具有相同大小的'Runnable []'數組,並使用第一個返回if條件下的bool(基本上是這個問題中的內容),則可以使用該索引執行第二陣列[λ]。 –

+0

聽起來好像我可能不得不寫一個新的類來覆蓋Runnable對象的run()方法(除非Runnable有一個支持返回基本類型的函數run()的方法)。 –

+0

@FiddleFreak lambda已經覆蓋了'Runnable'接口。我認爲Runnable的用法就是你陷入困境的地方。你能解釋一下你想用輸入螞蟻輸出細節來實現,而不是你正在使用的類的細節?沒有允許任何返回類型的'Runnable'方法。不過你可以使用'Callable'。 – RudolphEst