Java8中Lambda表達式的10個例子


Java8中Lambda表達式的10個例子 
例1 用Lambda表達式實現Runnable接口 

Java代碼   收藏代碼
  1. //Before Java 8:  
  2. new Thread(new Runnable() {  
  3. @Override  
  4. public void run() {  
  5.     System.out.println("Before Java8, too much code for too little to do");  
  6. }  
  7. }).start();  
  8. //Java 8 way:  
  9. new Thread( () -> System.out.println("In Java8, Lambda expression rocks !!") ).start();  



輸出: 
too much code, for too little to do 
Lambda expression rocks !! 
這個例子使我們學到了java8中Lambda表達式的書寫方式: 
(參數) -> 表達式 
(參數) -> 語句 
(參數) -> { 語句 } 
例如,如果你的方法只是在控制台打印信息,則可以這么寫: 

Java代碼   收藏代碼
  1. () -> System.out.println("Hello Lambda Expressions");  


如果你的方法接收兩個參數,那么: 

Java代碼   收藏代碼
  1. (int even, int odd) -> even + odd  


順帶提一句,一般來說在Lambda表達式中要盡量保持變量的簡潔性。這會使你的代碼簡短而能保持在一行之內。所以像上面的代碼可以選擇變量名類似a,b或者x,y之類的,比起even和odd來會更好。 

例2 用Lambda表達式寫事件監聽程序 
要是你用過Swing API,那就少不了事件監聽代碼,這是使用匿名類的經典例子。現在我們可以用Lambda表達式來抒寫更好的事件處理代碼。 

Java代碼   收藏代碼
  1. // Before Java 8:  
  2. JButton show = new JButton("Show");  
  3. show.addActionListener(new ActionListener() {  
  4.     @Override  
  5.     public void actionPerformed(ActionEvent e) {  
  6.         System.out.println("Event handling without lambda expression is boring");  
  7.     }  
  8. });  
  9. // Java 8 way:  
  10. show.addActionListener((e) -> {  
  11.     System.out.println("Light, Camera, Action !! Lambda expressions Rocks");  
  12. });  


另外一個常用匿名類的地方是給Collections.sort()方法提供自定義的Comparator接口實現。這個地方也可以用Lambda表達式。 

例3 用Lambda表達式進行List迭代 

Java代碼   收藏代碼
  1. //Prior Java 8 :  
  2. List features = Arrays.asList("Lambdas", "Default Method", "Stream API", "Date and Time API");  
  3. for (String feature : features) {  
  4.     System.out.println(feature);  
  5. }  
  6. //In Java 8:  
  7. List features = Arrays.asList("Lambdas", "Default Method", "Stream API", "Date and Time API");  
  8. features.forEach(n -> System.out.println(n));  


// 用java8的方法引用更好,方法引用由::(雙冒號)操作符來完成,看起來像c++中的作用域操作符 

Java代碼   收藏代碼
  1. features.forEach(System.out::println);  


輸出: 
Lambdas 
Default Method 
Stream API 
Date and Time API 

例4 使用Lambda表達式和函數式接口Predicate 
除了提供函數式編程語言級別的支持外,java8同時也新增了一個新的包java.util.function。其中包含了許多類來支持java函數式編程。其中之一是Predicate接口,使用這個接口和lamb表達式就可以以更少的代碼為API方法添加更多的動態行為。 
以下是Predicate的使用范例,展示了過濾集合數據的許多共性。 

Java代碼   收藏代碼
  1. public static void main(args[]){  
  2.     List languages = Arrays.asList("Java", "Scala", "C++", "Haskell", "Lisp");  
  3.     System.out.println("Languages which starts with J :");  
  4.     filter(languages, (str)->str.startsWith("J"));  
  5.     System.out.println("Languages which ends with a ");  
  6.     filter(languages, (str)->str.endsWith("a"));  
  7.     System.out.println("Print all languages :");  
  8.     filter(languages, (str)->true);  
  9.     System.out.println("Print no language : ");  
  10.     filter(languages, (str)->false);  
  11.     System.out.println("Print language whose length greater than 4:");  
  12.     filter(languages, (str)->str.length() > 4);  
  13. }  
  14. public static void filter(List names, Predicate condition) {  
  15.     for(String name: names) {  
  16.         if(condition.test(name)) {  
  17.             System.out.println(name + " ");  
  18.         }  
  19.     }  
  20. }  


輸出: 
Languages which starts with J : 
Java 
Languages which ends with a 
Java 
Scala 
Print all languages : 
Java 
Scala 
C++ 
Haskell 
Lisp 
Print no language : 
Print language whose length greater than 4: 
Scala 
Haskell 

Java代碼   收藏代碼
  1. //更佳的方式  
  2. public static void filter(List names, Predicate condition) {  
  3.     names.stream().filter((name) -> (condition.test(name))).forEach((name) -> {  
  4.         System.out.println(name + " ");  
  5.     });  
  6. }  


可以看到Stream API的filter方法也接受一個Predicate,意味着可以用內聯代碼直接替換我們自定義的filter()方法。這就是Lambda表達式的威力所在。除此之外Predicate接口也可以測試多個條件,將會在下面的例子中加以說明。

例5: Lambda表達式結合Predicate 
就像上個例子所說,Predicate允許組合兩個以上的條件,它提供了類似於邏輯與和或的操作and(),or()和xor(),這些方法可以用來組合傳遞到filter方法中的多個條件。例如為了獲取所有以J開頭並有四個字符長度的語言,可以定義兩個單獨的Predicate實例覆蓋每個條件然后用and方法將他們組合在一起。看例子: 

Java代碼   收藏代碼
  1. Predicate<String> startsWithJ = (n) -> n.startsWith("J");  
  2. Predicate<String> fourLetterLong = (n) -> n.length() == 4;  
  3. names.stream().filter(startsWithJ.and(fourLetterLong)).forEach((n) -> System.out.print("\nName, which starts with 'J' and four letter long is : " + n));  


類似可以用or或者xor。這個例子也強調了單獨用或者按需組合用Predicate的重要性。簡而言之用Predicate和Lambda表達式的優勢你可以寫的更少做得更多。 

例6 Map和Reduce的例子 
6.1 Map 
在這個例子中,我們要將costBeforeTax的每個元素以加上他們的增值稅。傳遞一個Lambda表達式給map方法使之應用於每個元素,之后在用forEach打印結果。 

Java代碼   收藏代碼
  1. // Without lambda expressions:  
  2. List costBeforeTax = Arrays.asList(100, 200, 300, 400, 500);  
  3. for (Integer cost : costBeforeTax) {  
  4.     double price = cost + .12*cost;  
  5.     System.out.println(price);  
  6. }   
  7. // With Lambda expression:  
  8. List costBeforeTax = Arrays.asList(100, 200, 300, 400, 500);  
  9. costBeforeTax.stream().map((cost) -> cost + .12*cost).forEach(System.out::println);  


輸出 
112.0 
224.0 
336.0 
448.0 
560.0 
112.0 
224.0 
336.0 
448.0 
560.0 
6.2 Reduce 
還有另外一個函數reduce可以將所有值轉換為一個值。map跟reduce操作是函數式編程的核心,reduce也被稱作折疊操作。reduce並不是一種新的操作,在SQL中我們用的一些聚集函數比如sum,avg,count等他們實際上也是reduce操作,因為他們也是將多個值進行操作然后返回一個值。Stream API定義了reduce函數,可以接受一個Lambda表達式然后組合所有值。Stream類中像IntStream都有內置的方法像average(), count(), sum(), mapToLong(), mapToDouble()等轉換方法。我們可以用內置的方法也可以自定義。 

Java代碼   收藏代碼
  1. // Old way:  
  2. List costBeforeTax = Arrays.asList(100, 200, 300, 400, 500);  
  3. double total = 0;  
  4. for (Integer cost : costBeforeTax) {  
  5.     double price = cost + .12*cost;  
  6.     total = total + price;  
  7. }  
  8. System.out.println("Total : " + total);  
  9. // New way:  
  10. List costBeforeTax = Arrays.asList(100, 200, 300, 400, 500);  
  11. double bill = costBeforeTax.stream().map((cost) -> cost + .12*cost).reduce((sum, cost) -> sum  
  12. + cost).get();  
  13. System.out.println("Total : " + bill);  


輸出 
Total : 1680.0 
Total : 1680.0 

例7 用filter創建一個字符串List 
在java開發中對大的集合進行過濾是常用的操作。用Lambda表達式和Stream API會讓操作變得簡單易懂。 
Stream提供了一個filter()方法,接受一個Predicate對象。這意味着可以傳遞一個Lambda表達式作為過濾邏輯,看例子: 

Java代碼   收藏代碼
  1. //創建一個長度大於兩個字符的字符串List  
  2. List<String> filtered = strList.stream().filter(x -> x.length()>  
  3. 2).collect(Collectors.toList());  
  4. System.out.printf("Original List : %s, filtered list : %s %n", strList, filtered);  


輸出 : 
Original List : [abc, , bcd, , defg, jk], filtered list : [abc, bcd, defg] 

例8 給每個List元素應用函數 
在工作中我們經常會碰到這樣的情況:給List中每個元素加以一定的操作例如乘以或者除以某個值等。這些操作用map方法再好不過了,我們可以將轉換邏輯以Lambda表達式傳給map方法來應用於每個元素: 
//將字符串轉為大寫然后用逗號連起來 

Java代碼   收藏代碼
  1. List<String> G7 = Arrays.asList("USA", "Japan", "France", "Germany", "Italy","U.K.","Canada");  
  2. String G7Countries = G7.stream().map(x -> x.toUpperCase()).collect(Collectors.joining(", "));  
  3. System.out.println(G7Countries);  


輸出: 
USA, JAPAN, FRANCE, GERMANY, ITALY, U.K., CANADA 

例9 復制不同值到子列表 
本例演示如何利用Stream類的distinct方法過濾重復值到集合中。 

Java代碼   收藏代碼
  1. List<Integer> numbers = Arrays.asList(9, 10, 3, 4, 7, 3, 4);  
  2. List<Integer> distinct = numbers.stream().map( i ->i*i).distinct().collect(Collectors.toList());  
  3. System.out.printf("Original List : %s, Square Without duplicates : %s %n", numbers, distinct);  


輸出 : 
Original List : [9, 10, 3, 4, 7, 3, 4], Square Without duplicates : [81, 100, 9, 16, 49] 

例10 計算List中元素的最大,最小,和以及平均值 
在Stream類中像IntStream, LongStream and DoubleStream有一個非常有用的方法summaryStattics(),返回IntSummaryStatistics, LongSummaryStatistics or DoubleSummaryStatistics其描述了這個流中元素的統計數據。下面的例子中我們用這個方法來計算一個List中的最大最小值總和以及均值: 

Java代碼   收藏代碼
  1. List<Integer> primes = Arrays.asList(2, 3, 5, 7, 11, 13, 17, 19, 23, 29);  
  2. IntSummaryStatistics stats = primes.stream().mapToInt((x) -> x).summaryStatistics();  
  3. System.out.println("Highest prime number in List : " + stats.getMax());  
  4. System.out.println("Lowest prime number in List : " + stats.getMin());  
  5. System.out.println("Sum of all prime numbers : " + stats.getSum());  
  6. System.out.println("Average of all prime numbers : " + stats.getAverage());  


輸出: 
Highest prime number in List : 29 
Lowest prime number in List : 2 
Sum of all prime numbers : 129 
Average of all prime numbers : 12.9


免責聲明!

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



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