java 8 的新特性(一)

https://www.runoob.com/java/java8-new-features.html

Lambda 表達式

Lambda 允許把函數作為一個方法的參數(函數作為參數傳遞到方法中)。

<code> (parameters) -> expression 或 (parameters) ->{ statements; }  /<code>可選類型聲明:不需要聲明參數類型,編譯器可以統一識別參數值。可選的參數圓括號:一個參數無需定義圓括號,但多個參數需要定義圓括號。可選的大括號:如果主體包含了一個語句,就不需要使用大括號。可選的返回關鍵字:如果主體只有一個表達式返回值則編譯器會自動返回值,大括號需要指定明表達式返回了一個數值。

<code>// 1. 不需要參數,返回值為 5 () -> 5 // 2. 接收一個參數(數字類型),返回其2倍的值 x -> 2 * x // 3. 接受2個參數(數字),並返回他們的差值 (x, y) -> x – y // 4. 接收2個int型整數,返回他們的和 (int x, int y) -> x + y // 5. 接受一個 string 對象,並在控制檯打印,不返回任何值(看起來像是返回void) (String s) -> System.out.print(s)/<code>

lambda 表達式只能引用標記了 final 的外層局部變量,這就是說不能在 lambda 內部修改定義在域外的局部變量,否則會編譯錯誤。

lambda 表達式的局部變量可以不用聲明為 final,但是必須不可被後面的代碼修改(即隱性的具有 final 的語義)


在 Lambda 表達式當中不允許聲明一個與局部變量同名的參數或者局部變量。



方法引用

方法引用提供了非常有用的語法,可以直接引用已有Java類或對象(實例)的方法或構造器。與lambda聯合使用,方法引用可以使語言的構造更緊湊簡潔,減少冗餘代碼。

方法引用通過方法的名字來指向一個方法。

方法引用可以使語言的構造更緊湊簡潔,減少冗餘代碼。

方法引用使用一對冒號 ::

Car 類中定義了 4 個方法作為例子來區分 Java 中 4 種不同方法的引用:

<code>package com.runoob.main; @FunctionalInterface public interface Supplier { T get(); } class Car { //Supplier是jdk1.8的接口,這裡和lamda一起使用了 public static Car create(final Supplier supplier) { return supplier.get(); } public static void collide(final Car car) { System.out.println("Collided " + car.toString()); } public void follow(final Car another) { System.out.println("Following the " + another.toString()); } public void repair() { System.out.println("Repaired " + this.toString()); } }/<code>

<code>構造器引用:它的語法是Class::new,或者更一般的Class< T >::new實例如下: final Car car = Car.create( Car::new ); final List

< Car > cars = Arrays.asList( car ); 靜態方法引用:它的語法是Class::static_method,實例如下: cars.forEach( Car::collide ); 特定類的任意對象的方法引用:它的語法是Class::method實例如下: cars.forEach( Car::repair ); 特定對象的方法引用:它的語法是instance::method實例如下: final Car police = Car.create( Car::new ); cars.forEach( police::follow ); /<code>



Java 8 函數式接口

函數式接口(Functional Interface)就是一個有且僅有一個抽象方法,但是可以有多個非抽象方法的接口。

函數式接口可以被隱式轉換為 lambda 表達式。

Lambda 表達式和方法引用(實際上也可認為是Lambda表達式)上。

<code>@FunctionalInterface interface GreetingService { void sayMessage(String message); }/<code>

那麼就可以使用Lambda表達式來表示該接口的一個實現(注:JAVA 8 之前一般是用匿名類實現的):

<code>GreetingService greetService1 = message -> System.out.println("Hello " + message);/<code>

函數式接口可以對現有的函數友好地支持 lambda。

JDK 1.8 之前已有的函數式接口:

java.lang.Runnablejava.util.concurrent.Callablejava.security.PrivilegedActionjava.util.Comparatorjava.io.FileFilterjava.nio.file.PathMatcherjava.lang.reflect.InvocationHandlerjava.beans.PropertyChangeListenerjava.awt.event.ActionListenerjavax.swing.event.ChangeListener

JDK 1.8 新增加的函數接口:

java.util.function

<code>java.util.function 它包含了很多類,用來支持 Java的 函數式編程,該包中的函數式接口有: 序號 接口 & 描述 1 BiConsumer 代表了一個接受兩個輸入參數的操作,並且不返回任何結果 2 BiFunction 代表了一個接受兩個輸入參數的方法,並且返回一個結果 3 BinaryOperator 代表了一個作用於於兩個同類型操作符的操作,並且返回了操作符同類型的結果 4 BiPredicate 代表了一個兩個參數的boolean值方法 5 BooleanSupplier 代表了boolean值結果的提供方 6 Consumer 代表了接受一個輸入參數並且無返回的操作 7 DoubleBinaryOperator 代表了作用於兩個double值操作符的操作,並且返回了一個double值的結果。 8 DoubleConsumer 代表一個接受double值參數的操作,並且不返回結果。 9 DoubleFunction 代表接受一個double值參數的方法,並且返回結果 10 DoublePredicate 代表一個擁有double值參數的boolean值方法 11 DoubleSupplier 代表一個double值結構的提供方 12 DoubleToIntFunction 接受一個double類型輸入,返回一個int類型結果。 13 DoubleToLongFunction 接受一個double類型輸入,返回一個long類型結果 14 DoubleUnaryOperator 接受一個參數同為類型double,返回值類型也為double 。 15 Function 接受一個輸入參數,返回一個結果。 16 IntBinaryOperator 接受兩個參數同為類型int,返回值類型也為int 。 17 IntConsumer 接受一個int類型的輸入參數,無返回值 。 18 IntFunction 接受一個int類型輸入參數,返回一個結果 。 19 IntPredicate 接受一個int輸入參數,返回一個布爾值的結果。 20 IntSupplier 無參數,返回一個int類型結果。 21 IntToDoubleFunction 接受一個int類型輸入,返回一個double類型結果 。 22 IntToLongFunction 接受一個int類型輸入,返回一個long類型結果。 23 IntUnaryOperator 接受一個參數同為類型int,返回值類型也為int 。 24 LongBinaryOperator 接受兩個參數同為類型long,返回值類型也為long。 25 LongConsumer 接受一個long類型的輸入參數,無返回值。 26 LongFunction 接受一個long類型輸入參數,返回一個結果。 27 LongPredicate R接受一個long輸入參數,返回一個布爾值類型結果。 28 LongSupplier 無參數,返回一個結果long類型的值。 29 LongToDoubleFunction 接受一個long類型輸入,返回一個double類型結果。 30 LongToIntFunction 接受一個long類型輸入,返回一個int類型結果。 31 LongUnaryOperator 接受一個參數同為類型long,返回值類型也為long。 32 ObjDoubleConsumer 接受一個object類型和一個double類型的輸入參數,無返回值。 33 ObjIntConsumer 接受一個object類型和一個int類型的輸入參數,無返回值。 34 ObjLongConsumer 接受一個object類型和一個long類型的輸入參數,無返回值。 35 Predicate 接受一個輸入參數,返回一個布爾值結果。 36 Supplier 無參數,返回一個結果。 37 ToDoubleBiFunction 接受兩個輸入參數,返回一個double類型結果 38 ToDoubleFunction 接受一個輸入參數,返回一個double類型結果 39 ToIntBiFunction 接受兩個輸入參數,返回一個int類型結果。 40 ToIntFunction 接受一個輸入參數,返回一個int類型結果。 41 ToLongBiFunction 接受兩個輸入參數,返回一個long類型結果。 42 ToLongFunction 接受一個輸入參數,返回一個long類型結果。 43 UnaryOperator 接受一個參數為類型T,返回值類型也為T。/<code>