Java8中Lambda表达式的10个例子
Java8中Lambda表達式的10個例子?
例1 用Lambda表達式實現(xiàn)Runnable接口?
- //Before?Java?8:??
- new?Thread(new?Runnable()?{??
- @Override??
- public?void?run()?{??
- ????System.out.println("Before?Java8,?too?much?code?for?too?little?to?do");??
- }??
- }).start();??
- //Java?8?way:??
- new?Thread(?()?->?System.out.println("In?Java8,?Lambda?expression?rocks?!!")?).start();??
輸出:?
too much code, for too little to do?
Lambda expression rocks !!?
這個例子使我們學(xué)到了java8中Lambda表達式的書寫方式:?
(參數(shù)) -> 表達式?
(參數(shù)) -> 語句?
(參數(shù)) -> { 語句 }?
例如,如果你的方法只是在控制臺打印信息,則可以這么寫:?
- ()?->?System.out.println("Hello?Lambda?Expressions");??
如果你的方法接收兩個參數(shù),那么:?
- (int?even,?int?odd)?->?even?+?odd??
順帶提一句,一般來說在Lambda表達式中要盡量保持變量的簡潔性。這會使你的代碼簡短而能保持在一行之內(nèi)。所以像上面的代碼可以選擇變量名類似a,b或者x,y之類的,比起even和odd來會更好。?
例2 用Lambda表達式寫事件監(jiān)聽程序?
要是你用過Swing API,那就少不了事件監(jiān)聽代碼,這是使用匿名類的經(jīng)典例子。現(xiàn)在我們可以用Lambda表達式來抒寫更好的事件處理代碼。?
- //?Before?Java?8:??
- JButton?show?=?new?JButton("Show");??
- show.addActionListener(new?ActionListener()?{??
- ????@Override??
- ????public?void?actionPerformed(ActionEvent?e)?{??
- ????????System.out.println("Event?handling?without?lambda?expression?is?boring");??
- ????}??
- });??
- //?Java?8?way:??
- show.addActionListener((e)?->?{??
- ????System.out.println("Light,?Camera,?Action?!!?Lambda?expressions?Rocks");??
- });??
另外一個常用匿名類的地方是給Collections.sort()方法提供自定義的Comparator接口實現(xiàn)。這個地方也可以用Lambda表達式。?
例3 用Lambda表達式進行List迭代?
- //Prior?Java?8?:??
- List?features?=?Arrays.asList("Lambdas",?"Default?Method",?"Stream?API",?"Date?and?Time?API");??
- for?(String?feature?:?features)?{??
- ????System.out.println(feature);??
- }??
- //In?Java?8:??
- List?features?=?Arrays.asList("Lambdas",?"Default?Method",?"Stream?API",?"Date?and?Time?API");??
- features.forEach(n?->?System.out.println(n));??
// 用java8的方法引用更好,方法引用由::(雙冒號)操作符來完成,看起來像c++中的作用域操作符?
- features.forEach(System.out::println);??
輸出:?
Lambdas?
Default Method?
Stream API?
Date and Time API?
例4 使用Lambda表達式和函數(shù)式接口Predicate?
除了提供函數(shù)式編程語言級別的支持外,java8同時也新增了一個新的包java.util.function。其中包含了許多類來支持java函數(shù)式編程。其中之一是Predicate接口,使用這個接口和lamb表達式就可以以更少的代碼為API方法添加更多的動態(tài)行為。?
以下是Predicate的使用范例,展示了過濾集合數(shù)據(jù)的許多共性。?
- public?static?void?main(args[]){??
- ????List?languages?=?Arrays.asList("Java",?"Scala",?"C++",?"Haskell",?"Lisp");??
- ????System.out.println("Languages?which?starts?with?J?:");??
- ????filter(languages,?(str)->str.startsWith("J"));??
- ????System.out.println("Languages?which?ends?with?a?");??
- ????filter(languages,?(str)->str.endsWith("a"));??
- ????System.out.println("Print?all?languages?:");??
- ????filter(languages,?(str)->true);??
- ????System.out.println("Print?no?language?:?");??
- ????filter(languages,?(str)->false);??
- ????System.out.println("Print?language?whose?length?greater?than?4:");??
- ????filter(languages,?(str)->str.length()?>?4);??
- }??
- public?static?void?filter(List?names,?Predicate?condition)?{??
- ????for(String?name:?names)?{??
- ????????if(condition.test(name))?{??
- ????????????System.out.println(name?+?"?");??
- ????????}??
- ????}??
- }??
輸出:?
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?
- //更佳的方式??
- public?static?void?filter(List?names,?Predicate?condition)?{??
- ????names.stream().filter((name)?->?(condition.test(name))).forEach((name)?->?{??
- ????????System.out.println(name?+?"?");??
- ????});??
- }??
可以看到Stream API的filter方法也接受一個Predicate,意味著可以用內(nèi)聯(lián)代碼直接替換我們自定義的filter()方法。這就是Lambda表達式的威力所在。除此之外Predicate接口也可以測試多個條件,將會在下面的例子中加以說明。
例5: Lambda表達式結(jié)合Predicate?
就像上個例子所說,Predicate允許組合兩個以上的條件,它提供了類似于邏輯與和或的操作and(),or()和xor(),這些方法可以用來組合傳遞到filter方法中的多個條件。例如為了獲取所有以J開頭并有四個字符長度的語言,可以定義兩個單獨的Predicate實例覆蓋每個條件然后用and方法將他們組合在一起。看例子:?
- Predicate<String>?startsWithJ?=?(n)?->?n.startsWith("J");??
- Predicate<String>?fourLetterLong?=?(n)?->?n.length()?==?4;??
- names.stream().filter(startsWithJ.and(fourLetterLong)).forEach((n)?->?System.out.print("\nName,?which?starts?with?'J'?and?four?letter?long?is?:?"?+?n));??
類似可以用or或者xor。這個例子也強調(diào)了單獨用或者按需組合用Predicate的重要性。簡而言之用Predicate和Lambda表達式的優(yōu)勢你可以寫的更少做得更多。?
例6 Map和Reduce的例子?
6.1 Map?
在這個例子中,我們要將costBeforeTax的每個元素以加上他們的增值稅。傳遞一個Lambda表達式給map方法使之應(yīng)用于每個元素,之后在用forEach打印結(jié)果。?
- //?Without?lambda?expressions:??
- List?costBeforeTax?=?Arrays.asList(100,?200,?300,?400,?500);??
- for?(Integer?cost?:?costBeforeTax)?{??
- ????double?price?=?cost?+?.12*cost;??
- ????System.out.println(price);??
- }???
- //?With?Lambda?expression:??
- List?costBeforeTax?=?Arrays.asList(100,?200,?300,?400,?500);??
- 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?
還有另外一個函數(shù)reduce可以將所有值轉(zhuǎn)換為一個值。map跟reduce操作是函數(shù)式編程的核心,reduce也被稱作折疊操作。reduce并不是一種新的操作,在SQL中我們用的一些聚集函數(shù)比如sum,avg,count等他們實際上也是reduce操作,因為他們也是將多個值進行操作然后返回一個值。Stream API定義了reduce函數(shù),可以接受一個Lambda表達式然后組合所有值。Stream類中像IntStream都有內(nèi)置的方法像average(), count(), sum(), mapToLong(), mapToDouble()等轉(zhuǎn)換方法。我們可以用內(nèi)置的方法也可以自定義。?
- //?Old?way:??
- List?costBeforeTax?=?Arrays.asList(100,?200,?300,?400,?500);??
- double?total?=?0;??
- for?(Integer?cost?:?costBeforeTax)?{??
- ????double?price?=?cost?+?.12*cost;??
- ????total?=?total?+?price;??
- }??
- System.out.println("Total?:?"?+?total);??
- //?New?way:??
- List?costBeforeTax?=?Arrays.asList(100,?200,?300,?400,?500);??
- double?bill?=?costBeforeTax.stream().map((cost)?->?cost?+?.12*cost).reduce((sum,?cost)?->?sum??
- +?cost).get();??
- System.out.println("Total?:?"?+?bill);??
輸出?
Total : 1680.0?
Total : 1680.0?
例7 用filter創(chuàng)建一個字符串List?
在java開發(fā)中對大的集合進行過濾是常用的操作。用Lambda表達式和Stream API會讓操作變得簡單易懂。?
Stream提供了一個filter()方法,接受一個Predicate對象。這意味著可以傳遞一個Lambda表達式作為過濾邏輯,看例子:?
- //創(chuàng)建一個長度大于兩個字符的字符串List??
- List<String>?filtered?=?strList.stream().filter(x?->?x.length()>??
- 2).collect(Collectors.toList());??
- 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元素應(yīng)用函數(shù)?
在工作中我們經(jīng)常會碰到這樣的情況:給List中每個元素加以一定的操作例如乘以或者除以某個值等。這些操作用map方法再好不過了,我們可以將轉(zhuǎn)換邏輯以Lambda表達式傳給map方法來應(yīng)用于每個元素:?
//將字符串轉(zhuǎn)為大寫然后用逗號連起來?
- List<String>?G7?=?Arrays.asList("USA",?"Japan",?"France",?"Germany",?"Italy","U.K.","Canada");??
- String?G7Countries?=?G7.stream().map(x?->?x.toUpperCase()).collect(Collectors.joining(",?"));??
- System.out.println(G7Countries);??
輸出:?
USA, JAPAN, FRANCE, GERMANY, ITALY, U.K., CANADA?
例9 復(fù)制不同值到子列表?
本例演示如何利用Stream類的distinct方法過濾重復(fù)值到集合中。?
- List<Integer>?numbers?=?Arrays.asList(9,?10,?3,?4,?7,?3,?4);??
- List<Integer>?distinct?=?numbers.stream().map(?i?->i*i).distinct().collect(Collectors.toList());??
- 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其描述了這個流中元素的統(tǒng)計數(shù)據(jù)。下面的例子中我們用這個方法來計算一個List中的最大最小值總和以及均值:?
- List<Integer>?primes?=?Arrays.asList(2,?3,?5,?7,?11,?13,?17,?19,?23,?29);??
- IntSummaryStatistics?stats?=?primes.stream().mapToInt((x)?->?x).summaryStatistics();??
- System.out.println("Highest?prime?number?in?List?:?"?+?stats.getMax());??
- System.out.println("Lowest?prime?number?in?List?:?"?+?stats.getMin());??
- System.out.println("Sum?of?all?prime?numbers?:?"?+?stats.getSum());??
- 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
轉(zhuǎn)載于:https://www.cnblogs.com/zkycode/p/6251488.html
總結(jié)
以上是生活随笔為你收集整理的Java8中Lambda表达式的10个例子的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java内存分配--引用
- 下一篇: 求一个好听的古代小说名字