1. 程式人生 > 其它 >第六週 Java8新特性

第六週 Java8新特性

一、Lambda表示式

Lambda表示式是一個匿名函式,即沒有函式名的函式。從動態引用到動態定義,可以簡化寫法。

對比兩種寫法:

Lambda表示式的語法如下:

(parameters) -> expression
或
(parameters) ->{ statements; }

還有如下特性:

  • 可選型別宣告:不需要宣告引數型別,由編譯器統一識別引數值
  • 可選引數的圓括號:一個引數時可以不要寫括號,多個引數需要寫括號,如下面例子中的2例和3例
  • 可選的大括號:只有一行時可以不用寫大括號
  • 可選的返回關鍵字:如果只有一個返回值,則編譯器可以自動返回,如例1,沒有寫成return 5;

示例:

  1. 不需要引數,返回值為5

() -> 5

  1. 接受一個引數,返回乘以2的值

x -> x*2

  1. 接受2個引數,並返回他們的差

(x,y) -> x-y

  1. 接受兩個int型別的整數,返回他們的和

(int x,int y) -> x+y

  1. 接受一個String型別的引數,不返回值

(String x) -> System.out.print(x)

Java8給我們提供了一些介面,可供使用:

  • Predicate 有引數、條件判斷
  • Function<T, R> 有引數、有返回值
  • Consumer 無返回值
  • Supplier 無引數、有返回值

還有很多,都在java.util.function包裡面。

示例:

//java7寫法
new Thread(new Runnable() {
    @Override
    public void run() {
        System.out.println(new Date());
    }
}).start();

//java8 寫法
new Thread(()-> System.out.println(new Date())).start();

二、Stream

Stream(流)是一個來自資料來源的元素佇列並支援聚合操作

  • 元素 : 特定型別的物件,形成一個佇列。Java中的Stream並不會儲存元素,而是按需計算。
  • 資料來源:流的來源。 可以是集合,陣列,I/O channel, 產生器 generator 等。
  • 聚合操作 類似 SQL 語句一樣的操作, 比如 filter, map, reduce, find, match, sorted 等。
  • 和以前的 Collection 操作不同, Stream 操作還有兩個基礎的特徵:
  • Pipelining:中間操作都會返回流物件本身。這樣多個操作可以串聯成一個管道, 如同流式風格(fluent style)。這樣做可以對操作進行優化,比如延遲執行(laziness)和短路((short-circuiting)。
  • 內部迭代:以前對集合遍歷都是通過 Iterator 或者 For-Each 的方式, 顯式的在集合外部進行迭代,這叫做外部迭代。Stream提供了內部迭代的方式, 通過訪問者模式(Visitor)實現。

建立Stream的幾種方式:

  1. 使用陣列
   String[] array={"a","b","c","d"};
   Stream<String> stream1 = Stream.of(array);
   Stream<String> stream2 = Arrays.stream(array);
  1. 使用Collections
List<Integer> list=new ArrayList<>();
list.add(1);
list.add(2);
list.add(3);
list.add(4);
list.stream();
  1. 使用Stream.generate()
 Stream<String> stream3 = Stream.generate(() -> "love").limit(10);
  1. 使用Stream.iterate()
Stream<BigInteger> bigIntStream = Stream.iterate(BigInteger.ZERO, n -> n.add(BigInteger.ONE)).limit(10);
  1. 其他API建立
Stream stream = Stream.concat(stream1, stream2);
Stream<String> wordStream = Pattern.compile("\\W").splitAsStream(sentence);

Stream操作:

中間操作:

  1. 選擇與過濾
  • filter(Predicate p) 接收Lambda,從流中排除某些元素
  • distinct() 篩選,通過流生成的元素的hashCode()與equals()去除重複元素
  • limit(long maxSize)截斷流,使其元素不超過指定數量
  • skip(long n)跳過元素,返回一個扔掉了前n個元素的流。
  1. 對映
  • map(Function f)接收Lambda將元素轉換成其他形式或提取資訊;接收一個函式作為引數,該函式會被應用到每個元素上,並將其對映成一個新的元素
  • mapToDouble(ToDoubleFunction f) 接收一個函式作為引數,該函式會被應用到每個元素上,產生一個新的 DoubleStream。
  • mapToInt(ToIntFunction f) 接收一個函式作為引數,該函式會被應用到每個元素上,產生一個新的 IntStream。
  • flatMap(Function f) 接收一個函式作為引數,將流中的每個值都換成另一個流,然後把所有流連線成一個流
  1. 排序
  • sorted() 產生一個按自然順序排序的流
  • sorted(Comparator comp) 產生一個新流,按比較器順序排序

終止操作:

  1. 查詢與匹配
  • allMatch 檢查是否匹配所有元素
  • anyMatch 檢查是否至少匹配一個元素
  • noneMatch 檢查是否沒有匹配的元素
  • findFirst 返回第一個元素
  • findAny 返回當前流中的任意元素
  • count 返回流中元素的總個數
  • max 返回流中的最大值
  • min 返回流中的最小值
  1. 規約 reduce
  2. 收集 collect
  • toList 把流中元素收集到List
  • toSet 把流中元素收集到set
  • toCollection Collection 把流中元素收集到建立的集合
  • count 計算流中元素的個數
  • summaryStatistics 統計最大最小平均值
  1. 迭代
  • forEach

程式碼示例:

 public static void main(String[] args) {
        List<Integer> list=new ArrayList<>();
        list.add(1);
        list.add(2);
        list.add(3);
        list.add(4);

        list.stream().filter(x->x>2).forEach(System.out::println);

        list.stream().mapToDouble(x->Double.valueOf(x)).forEach((b)-> System.out.println(b));

        list.stream().flatMap(x->Arrays.stream(new Integer[]{x})).forEach(System.out::println);

        boolean flag = list.stream().anyMatch(x -> x % 3 == 0);

        long count = list.stream().count();
        System.out.println("元素個數:"+count);

        long sum = list.stream().collect(Collectors.summarizingInt(x -> x)).getSum();
        System.out.println("總元素的和是:"+sum);

        Integer integer = list.stream().reduce((a, b) -> a + b).get();
        System.out.println("規約求和:"+integer);

    }