1. 程式人生 > 實用技巧 >【JAVA應用】Lambda表示式

【JAVA應用】Lambda表示式

JDK8新特性

新特性

  1. Lambda表示式和@FunctionnalInterface註解
  2. Stream類
  3. 移除PermGen空間,加入Metaspace
  4. Optional
  5. 時間工具類
  6. 反射獲取class的方法能獲取到真實的引數名了,之前只能獲取到編譯後的變數,是一個替換的變數

Lambda

優點

  1. 函數語言程式設計是程式語言的發展方向,而java要順應這個趨勢,而lambda又是函數語言程式設計的基礎內容,所以現在好處一是順應了程式語言的發展趨勢
  2. 程式碼簡潔,可讀性變高了
  3. 改善了集合的操作,map,reduce,filter提供了並行化
  4. 對遞迴做了一定的優化遞迴優化,尾遞迴優化一般操作中我們不會關注到,如果你用Lambda,他會自己編譯幫你實現

缺點

  1. 調式麻煩
  2. 新的方式,有學習成本
  3. 型別不明確,轉換不方便
  4. 平行計算需要預熱,而且只對Collection支援的比較好,其他型別支援一般,沒有平行計算的話一般情況下比for迴圈要慢

jdk8中Stream比你用for迴圈慢5倍

慢的原因

  1. for迴圈畢竟一直存在的,JIT已經對他進行了長時間的優化
  2. for迴圈對快取是友好的,而Stream則還沒有做到這一點,所以如果是int基本型別的話,差距會打,但是如果是引用型別Integer的話差距就不大了
  3. 但是如果你用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());

}