Java 8 函式式介面 : Supplier、Function、Consumer、Predicate
函式式介面特點
1、三種方法
- 唯一的抽象方法
- 使用default定義普通方法(預設方法),通過物件呼叫。
- 使用static定義靜態方法,通過介面名呼叫。
2、一個新註解@FunctionInterface 如果某一個介面就是為了函式式介面而生的,使用註解@FunctionalInterface告訴編譯器這是一個函式式介面,明確這個函式中只有一個抽象方法,當你嘗試在介面中編寫多個抽象方法的時候編譯器將不允許,但是可以有多個非抽象方法。 不過Object類的方法可以定義為抽象方法,因為介面的實現類一定是Object的子類。
3、實現方式 JDK8以前,通過匿名內部類實現函式式介面
new Thread(new Runnable() { @Override public void run() { System.out.println("Hello world !"); } }).start();
JDK8以後可以使用lambda 表示式來實現,lambda表示式就是為了優化匿名內部類而生。
Runnable r = () -> System.out.println("task running !");
new Thread(() -> System.out.println("task running !")).start();
JDK提供的函式式介面
1. JDK 1.8之前已有函式式介面,比如: java.lang.Runnable java.util.concurrent.Callable java.util.Comparator
2. JDK 1.8 新增加的函式介面包:
型別 | 介面 | 引數 | 返回值 | 描述 |
---|---|---|---|---|
供給型介面 | Supplier<T> | None | T | 沒有輸入,返回一個物件T |
功能型函式式介面 | Function<T, R> | T | R | 物件轉換,T->R |
消費型介面 | Consumer<T> | T | void | 改變物件T內部屬性的值 |
斷言型介面 | Predicate<T> | T | boolean | 進行邏輯判斷,返回boolean值 |
其他 |
供給型介面 Supplier<T> JDK 8 原始碼
@FunctionalInterface
public interface Supplier<T> {
//返回T
T get();
}
使用
Supplier<String> supplier = ()-> "Hello World!";
Supplier<String> supplier = ()-> new User();
功能型函式式介面 Function<T, R> 接受一個輸入引數T,返回一個結果R。 JDK8 原始碼如下
@FunctionalInterface
public interface Function<T, R> {
R apply(T t);
default <V> Function<V, R> compose(Function<? super V, ? extends T> before) {
Objects.requireNonNull(before);
return (V v) -> apply(before.apply(v));
}
default <V> Function<T, V> andThen(Function<? super R, ? extends V> after) {
Objects.requireNonNull(after);
return (T t) -> after.apply(apply(t));
}
static <T> Function<T, T> identity() {
return t -> t;
}
}
lambda 表示式實現Function介面
Function<String,Long> fun = str -> Long.valueOf(str);
Function<Integer,String> fun = item -> item+"";
Consumer<T> 消費型介面 An operation which accepts a single input argument and returns no result. Unlike most other functional interfaces, Consumer is expected to operate via side-effects. 一個接受單個輸入引數並且不返回結果的操作。 與大多數其他函式介面不同, Consumer介面期望通過副作用進行操作。
Consumer介面JDK8 原始碼如下
@FunctionalInterface
public interface Consumer<T> {
/**
* Performs this operation on the given argument.
* 對給定的引數執行此操作
* @param t the input argument
*/
void accept(T t);
default Consumer<T> andThen(Consumer<? super T> after) {
//after == null 則拋異常 NullPointerException()
Objects.requireNonNull(after);
return (T t) -> { accept(t); after.accept(t); };
}
}
accept()接受並改變某個物件的內部值
user -> user.setAge(20);
Predicate<T> 斷言型介面 JDK8 原始碼如下
@FunctionalInterface
public interface Predicate<T> {
//進行某些邏輯判斷並返回一個boolean值
boolean test(T t);
//與
default Predicate<T> and(Predicate<? super T> other) {
Objects.requireNonNull(other);
return (t) -> test(t) && other.test(t);
}
//取反
default Predicate<T> negate() {
return (t) -> !test(t);
}
default Predicate<T> or(Predicate<? super T> other) {
Objects.requireNonNull(other);
return (t) -> test(t) || other.test(t);
}
static <T> Predicate<T> isEqual(Object targetRef) {
return (null == targetRef)
? Objects::isNull
: object -> targetRef.equals(object);
}
}
lambda 表示式實現Predicate介面
Predicate<Integer> predicate = age -> age > 18;
Predicate<String> predicate = str -> str != null;
Predicate常用於集合的過濾,得到一個新的集合 Stream filter(Predicate<? super T> predicate);
List<Long> supplierIds = page.getContent().stream().map(item -> item.getSupplierId()).distinct()
.filter(item -> item != null).collect(Collectors.toList());