Java8 函數式接口 @FunctionalInterface以及常用Consumer、Supplier、Function、Predicate總結
首先看看什麼是Lambda 表達式
Lambda是一個匿名函數,我們可以把Lambda表達式理解為一段可以傳遞的代碼(將代碼像數據一樣傳遞);最簡單的Lambda表達式可由逗號分隔的參數列表、->符號和語句塊組成,例如:
Arrays.asList( "a", "b", "d" ).forEach( e -> System.out.println( e ) );
如果 ->後面的語句塊有多句就使用 { } 例如:
Arrays.asList("a", "b", "d").forEach(i -> {
if ("a".equals(i)) {
System.out.println(i);
}
});
@FunctionalInterface 註解 標識是一個函數式接口
1、該註解只能標記在”有且僅有一個抽象方法”的接口上。
2、JDK8接口中的靜態方法和默認方法,都不算是抽象方法。
3、接口默認繼承java.lang.Object,所以如果接口顯示聲明覆蓋了Object中方法,那麼也不算抽象方法。
4、該註解不是必須的,如果一個接口符合”函數式接口”定義,那麼加不加該註解都沒有影響。加上該註解能夠更好地讓編譯器進行檢查。如果編寫的不是函數式接口,但是加上了@FunctionInterface,那麼編譯器會報錯。
函數式接口創建三種方式
1、lambda表達式
2、方法引用
3、構造方法引用
Java8中強制申明的常用函數式接口
Runnable、Callable
java.util.function包中常用接口
Function<T, R>接口
Function 接口是一個功能型接口,是一個轉換數據的作用。接收一個T參數,返回一個R結果
Function 接口實現 apply 方法來做轉換。
Stream 類的 map 方法了,map 方法傳入一個 Function 接口,返回一個轉換後的 Stream類
public static void main(String[] args) {
//使用map方法,泛型的第一個參數是轉換前的類型,第二個是轉化後的類型
Function<String, Integer> function = s -> {
System.out.println("獲取字符串" + s + "的長度");
return s.length();
};
Stream<String> stream = Stream.of("sada", "dfg", "12");
Stream<Integer> stream1 = stream.map(function);
stream1.forEach(System.out::println);
}
Consumer接口
消費型接口,接收一個參數,並處理,不返回
public static void main(String[] args) {
Consumer<Integer> consumer = i -> {
System.out.println("Consumer 接收 參數 i 開始處理");
int step = 1;
System.out.printf("Consumer 輸入%d, 輸出%d%n", i, i + step);
};
List<Integer> list = Arrays.asList(4, 2, 6);
list.forEach(consumer);
}
Predicate接口
Predicate 接口是一個謂詞型接口,是一個類似於 bool 類型的判斷的接口。接收一個T類型參數,返回一個bool值
Stream的filter接口參數為Predicate<? super T>
public static void main(String[] args) {
//將Predicate作為filter接口,Predicate起到一個判斷的作用
Predicate<Integer> predicate = integer -> integer > 4;
Stream<Integer> stream = Stream.of(1,3,2,4,5,12,13);
List<Integer> list = stream.filter(predicate).collect(Collectors.toList());
list.forEach(System.out::println);
}
Supplier接口
生產者接口,沒有參數,返回一個T類型的結果。
1、Supplier 接口可以理解為一個容器,用於裝數據的。
2、Supplier 接口有一個 get 方法,可以返回值。
Optional中的 orElseGet 方法的參數就是Supplier<? extends T>
Stream<Integer> stream = Stream.of(1, 2, 3, 4);
//返回一個optional對象
Optional<Integer> first = stream.filter(i -> i > 4)
.findFirst();
//optional對象有需要Supplier接口的方法
//orElse,如果first中存在數,就返回這個數,如果不存在,就放回傳入的數
System.out.println(first.orElse(1));
System.out.println(first.orElse(7));
Supplier<Integer> supplier = new Supplier<Integer>() {
@Override
public Integer get() {
//返回一個隨機值
return new Random().nextInt();
}
};
//orElseGet,如果first中存在數,就返回這個數,如果不存在,就返回supplier返回的值
System.out.println(first.orElseGet(supplier));