《JAVA8實戰》讀書筆記之傳遞方法和傳遞lambda


傳遞方法:

假設 你有一個Apple類,它 有一個getColor方法,還有一個變量inventory保存着一個Apples的列表。你可能想要選出所 有的綠蘋果,並返回一個列表。通常我們用篩選(filter)一詞來表達這個概念。在Java 8之前, 你可能會寫這樣一個方法filterGreenApples:

 1 public static List<Apple> filterGreenApples( List<Apple> inventory )
 2 {
 3     List<Apple> result = new ArrayList<>(); for ( Apple apple : inventory )
 4     {
 5         if ( "green".equals( apple.getColor() ) )
 6         {
 7             result.add( apple );
 8         }
 9     }
10     return(result);
11 }

 

但是接下來,有人可能想要選出重的蘋果,比如超過150克: 

 public static List<Apple> filterHeavyApples( List<Apple> inventory )
{
     List<Apple> result = new ArrayList<>();
     for ( Apple apple : inventory )
     {
        if ( apple.getWeight() > 150 )
        {
             result.add( apple );
         }
     }
     return(result);
 }

這 兩個方法只有一行不同: if里面高亮的那行條件。

Java 8你可以這樣寫:

 1 public static boolean isGreenApple( Apple apple )
 2 {
 3     return("green".equals( apple.getColor() ) );
 4 }
 5 
 6 
 7 public static boolean isHeavyApple( Apple apple )
 8 {
 9     return(apple.getWeight() > 150);
10 }
11 
12 
13 public interface Predicate<T>{ 
14     boolean test( T t ); 
15 } 
16 
17 static List<Apple> filterApples( List<Apple> inventory, Predicate<Apple> p )
18 {
19     List<Apple> result = new ArrayList<>();
20     for ( Apple apple : inventory )
21     {
22         if ( p.test( apple ) )
23         {
24             result.add( apple );
25         }
26     }
27     return(result);
28 }        

要用它的話,你可以寫: 

1 filterApples(inventory, Apple::isGreenApple);
2 或者 
3 filterApples(inventory, Apple::isHeavyApple);

 

注:

什么是謂詞? 前 面 的 代 碼 傳 遞 了 方 法 Apple::isGreenApple ( 它 接 受 參 數 Apple 並 返 回 一 個 boolean)給filterApples,后者則希望接受一個Predicate<Apple>參數。謂詞(predicate)它接受一個參數值,並返回true或false。你 在后面會看到, Java 8也會允許你寫Function<Apple,Boolean>,但用Predicate<Apple>是更標准的方式,效率也會更高一 點兒,這避免了把boolean封裝在Boolean里面

 

傳遞 Lambda

把方法作為值來傳遞顯然很有用,但要是為類似於isHeavyApple和isGreenApple這種可能只用一兩次的短方法寫一堆定義有點兒煩人。不過Java 8也解決了這個問題,它引入了一套新
記法(匿名函數或Lambda),讓你可以寫

filterApples(inventory, (Apple a) -> "green".equals(a.getColor()) );

或者

filterApples(inventory, (Apple a) -> a.getWeight() > 150 );

甚至

filterApples(inventory, (Apple a) -> a.getWeight() < 80 || "brown".equals(a.getColor()) );


所以,你甚至都不需要為只用一次的方法寫定義;代碼更干凈、更清晰,因為你用不着去找自己到底傳遞了什么代碼。但要是Lambda的長度多於幾行(它的行為也不是一目了然)的話,那你還是應該用方法引用來指向一個有描述性名稱的方法,而不是使用匿名的Lambda。你應該以代碼的清晰度為准繩。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM