第六週 Java8新特性
阿新 • • 發佈:2021-06-21
一、Lambda表示式
Lambda表示式是一個匿名函式,即沒有函式名的函式。從動態引用到動態定義,可以簡化寫法。
對比兩種寫法:
Lambda表示式的語法如下:
(parameters) -> expression
或
(parameters) ->{ statements; }
還有如下特性:
- 可選型別宣告:不需要宣告引數型別,由編譯器統一識別引數值
- 可選引數的圓括號:一個引數時可以不要寫括號,多個引數需要寫括號,如下面例子中的2例和3例
- 可選的大括號:只有一行時可以不用寫大括號
- 可選的返回關鍵字:如果只有一個返回值,則編譯器可以自動返回,如例1,沒有寫成return 5;
示例:
- 不需要引數,返回值為5
() -> 5
- 接受一個引數,返回乘以2的值
x -> x*2
- 接受2個引數,並返回他們的差
(x,y) -> x-y
- 接受兩個int型別的整數,返回他們的和
(int x,int y) -> x+y
- 接受一個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的幾種方式:
- 使用陣列
String[] array={"a","b","c","d"};
Stream<String> stream1 = Stream.of(array);
Stream<String> stream2 = Arrays.stream(array);
- 使用Collections
List<Integer> list=new ArrayList<>();
list.add(1);
list.add(2);
list.add(3);
list.add(4);
list.stream();
- 使用Stream.generate()
Stream<String> stream3 = Stream.generate(() -> "love").limit(10);
- 使用Stream.iterate()
Stream<BigInteger> bigIntStream = Stream.iterate(BigInteger.ZERO, n -> n.add(BigInteger.ONE)).limit(10);
- 其他API建立
Stream stream = Stream.concat(stream1, stream2);
Stream<String> wordStream = Pattern.compile("\\W").splitAsStream(sentence);
Stream操作:
中間操作:
- 選擇與過濾
- filter(Predicate p) 接收Lambda,從流中排除某些元素
- distinct() 篩選,通過流生成的元素的hashCode()與equals()去除重複元素
- limit(long maxSize)截斷流,使其元素不超過指定數量
- skip(long n)跳過元素,返回一個扔掉了前n個元素的流。
- 對映
- map(Function f)接收Lambda將元素轉換成其他形式或提取資訊;接收一個函式作為引數,該函式會被應用到每個元素上,並將其對映成一個新的元素
- mapToDouble(ToDoubleFunction f) 接收一個函式作為引數,該函式會被應用到每個元素上,產生一個新的 DoubleStream。
- mapToInt(ToIntFunction f) 接收一個函式作為引數,該函式會被應用到每個元素上,產生一個新的 IntStream。
- flatMap(Function f) 接收一個函式作為引數,將流中的每個值都換成另一個流,然後把所有流連線成一個流
- 排序
- sorted() 產生一個按自然順序排序的流
- sorted(Comparator comp) 產生一個新流,按比較器順序排序
終止操作:
- 查詢與匹配
- allMatch 檢查是否匹配所有元素
- anyMatch 檢查是否至少匹配一個元素
- noneMatch 檢查是否沒有匹配的元素
- findFirst 返回第一個元素
- findAny 返回當前流中的任意元素
- count 返回流中元素的總個數
- max 返回流中的最大值
- min 返回流中的最小值
- 規約 reduce
- 收集 collect
- toList 把流中元素收集到List
- toSet 把流中元素收集到set
- toCollection Collection
把流中元素收集到建立的集合 - count 計算流中元素的個數
- summaryStatistics 統計最大最小平均值
- 迭代
- 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);
}