【JAVA應用】Lambda表示式
阿新 • • 發佈:2020-08-05
JDK8新特性
- Lambda表示式和@FunctionnalInterface註解
- Stream類
- 移除PermGen空間,加入Metaspace
- Optional
- 時間工具類
- 反射獲取class的方法能獲取到真實的引數名了,之前只能獲取到編譯後的變數,是一個替換的變數
Lambda
優點
- 函數語言程式設計是程式語言的發展方向,而java要順應這個趨勢,而lambda又是函數語言程式設計的基礎內容,所以現在好處一是順應了程式語言的發展趨勢
- 程式碼簡潔,可讀性變高了
- 改善了集合的操作,map,reduce,filter提供了並行化
- 對遞迴做了一定的優化遞迴優化,尾遞迴優化一般操作中我們不會關注到,如果你用Lambda,他會自己編譯幫你實現
缺點
- 調式麻煩
- 新的方式,有學習成本
- 型別不明確,轉換不方便
- 平行計算需要預熱,而且只對Collection支援的比較好,其他型別支援一般,沒有平行計算的話一般情況下比for迴圈要慢
jdk8中Stream比你用for迴圈慢5倍
- for迴圈畢竟一直存在的,JIT已經對他進行了長時間的優化
- for迴圈對快取是友好的,而Stream則還沒有做到這一點,所以如果是int基本型別的話,差距會打,但是如果是引用型別Integer的話差距就不大了
- 但是如果你用CPU密集型的操作的話,如果用到了Stream的平行計算,那麼差距就會變小了
形成上面的根本原因是
Lambda的實現方式
Lambda實現
Lambda其實就是生成了私有方法,內容就是你在大括號中定義的,最後替換而已,如果你定義了一樣的話他會在執行期報錯,這個我覺得應該在編譯器就報錯的,或者編譯器替換成一個不一樣的
stream應用
public static void main(String[] args) { String[] strings = new String[]{"a","bbb","cc","bbb"}; System.out.println("\n1. allMatch: 是否所有斷言都通過,Predicate:就是定義的一個斷言類"); System.out.println(Arrays.stream(strings).allMatch(x -> x.startsWith("a"))); System.out.println("\n2. anyMatch: 任何一個匹配都通過"); System.out.println(Arrays.stream(strings).anyMatch(x -> x.startsWith("a"))); System.out.println("\n3. forEach: 並行遍歷,輸出順序可能和定義的不一致"); Arrays.stream(strings).forEach(x -> System.out.printf("%s\t", x)); System.out.println("\n\n4. forEachOrdered: 順序遍歷,輸出順序和定義的一致"); Arrays.stream(strings).forEachOrdered(x -> System.out.printf("%s\t", x)); System.out.println("\n\n5 collect: 對流進行收集,傳入一個收集器Collector,可以使用Collectors提供的方法"); System.out.println(Arrays.stream(strings).collect(Collectors.joining(","))); System.out.println("\n6 noneMatch: 任何一個都不匹配成功才返回true"); System.out.println(Arrays.stream(strings).noneMatch(x -> x.startsWith("b"))); System.out.println("\n7 count: 總數"); System.out.println(Arrays.stream(strings).count()); System.out.println("\n8 distinct: 返回去重以後的stream"); Arrays.stream(strings).distinct().forEach(x -> System.out.printf("%s\t",x)); System.out.println("\n\n9. filter: 過濾"); Arrays.stream(strings).filter(x -> x.startsWith("a")).forEach(x -> System.out.println(x)); System.out.println("\n10. findAny: 只要有任意一個數據就可以返回,返回的是Optional"); System.out.println(Arrays.stream(strings).findAny().get()); System.out.println("\n11. findFirst: 返回第一個,返回的是Optional"); System.out.println(Arrays.stream(strings).findFirst().get()); System.out.println("\n12. limit: 擷取前幾個"); Arrays.stream(strings).limit(2).forEach(x -> System.out.printf("%s\t",x)); System.out.println("\n\n13. max: 通過Comparator方法進行排序,返回最大值"); System.out.println(Arrays.stream(strings).max((x, y) -> x.compareTo(y)).get()); System.out.println("\n\n14. min: 通過Comparator方法進行排序,返回最小值"); System.out.println(Arrays.stream(strings).min((x, y) -> x.compareTo(y)).get()); System.out.println("\n15. peek: peek是瞥一眼的意思,這裡簡單理解就是隻能看一下但是不能動," + "和map的區別是即便操作了資料返回的stream也不受影響" + "和forEach的區別是peek返回的還是流,而forEach沒有返回值"); Arrays.stream(strings).peek(x -> x.substring(0,1)).forEach(x -> System.out.printf("%s\t", x)); System.out.println("\n\n16. skip: 跳過指定位置的資料"); Arrays.stream(strings).skip(1).forEach(x -> System.out.printf("%s\t", x)); System.out.println("\n\n17. sorted: 預設按升序排序,可以自定義排序"); Arrays.stream(strings).sorted().forEach(x -> System.out.printf("%s\t", x)); System.out.println("\n\n18. toArray: 不指定返回型別,預設返回Object"); for (Object o : Arrays.stream(strings).toArray()) { System.out.printf("%s\t", o); } System.out.println("\n\n19. toArray: 指定返回型別"); for (String s : Arrays.stream(strings).toArray(String[]::new)) { System.out.printf("%s\t", s); } System.out.println("\n\n20. map: 遍歷操作"); Arrays.stream(strings).map(x -> System.out.printf("%s\t",x)); String[][] strings1 = new String[][]{{"a","b","c"},{"e","f","g"}}; System.out.println("\n\n21. flatMap: flat是扁平的意思,flatMap可以用來把二維資料拉平到一維的"); Arrays.stream(strings1).flatMap(x -> Arrays.stream(x)).forEach(x -> System.out.printf("%s\t",x)); System.out.println("\n\n22. flatMapToInt: 要求遍歷的是IntStream"); Arrays.stream(strings).flatMapToInt(x -> IntStream.of(x.length())).forEach(x -> System.out.printf("%s\t",x)); System.out.println("\n\n23. reduce: 聚合操作"); System.out.println(Arrays.stream(strings).reduce((x,y) -> x+y).get()); }