---
tags: Java
---
# 函式介面 - Consumer、Function、Predicate 與 Supplier
## 前言
補充關於 Consumer、Function、Predicate 與 Supplier 的一些資訊。
## 目錄
* [前言](#前言)
* [目錄](#目錄)
* [介紹/基本概念](#介紹/基本概念)
* [Consumer](#Consumer)
* [Supplier](#Supplier)
* [Predicate](#Predicate)
* [Function](#Function)
* [實作過程](#實作過程)
* [Consumer 的實作過程](#Consumer-的實作過程)
* [Supplier 的實作過程](#Supplier-的實作過程)
* [Predicate 的實作過程](#Predicate-的實作過程)
* [Function 的實作過程](#Function-的實作過程)
* [參考資料](#參考資料)
## 介紹/基本概念
### Consumer
Consumer Interface 是一個消費型的介面,裡面長這樣,有兩個方法,一個 accept 和默認 andThen 方法,通過傳入參數,然後輸出值,大概是這樣的方法,常常會搭配 Stream 一起使用。
```java=
@FunctionalInterface
public interface Consumer<T> {
void accept(T t);
default Consumer<T> andThen(Consumer<? super T> after) {
Objects.requireNonNull(after);
return (T t) -> { accept(t); after.accept(t); };
}
}
```
### Supplier
Supplier 是個供給型的介面,就像是一個容器,負責儲存資料和值。
```java=
@FunctionalInterface
public interface Supplier<T> {
T get();
}
```
### Predicate
Predicate 是一個判斷 bool 的介面。
```java=
@FunctionalInterface
public interface Predicate<T> {
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);
}
@SuppressWarnings("unchecked")
static <T> Predicate<T> not(Predicate<? super T> target) {
Objects.requireNonNull(target);
return (Predicate<T>)target.negate();
}
}
```
### Function
Function 是功能型介面,它的作用是將輸入資料轉出成另一種形式的輸出資料。
```java=
@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;
}
}
```
## 實作過程
### Consumer 的實作過程
#### 1. 使用 Consumer 介面實現方法
```java=
public class ConsumerDemo1 {
public static void main(String[] args) {
Consumer<String> eatHamburger = new Consumer<String>() {
@Override
public void accept(String customer) {
System.out.println(customer +" eats a hamburger");
}
};
Stream<String> customers = Stream.of("Eric", "Tony", "Erica", "Daniel", "Sophia");
customers.forEach(eatHamburger);
}
}
```

#### 2. 使用 lambda 實現 Consumer
```java=
public class ConsumerDemo2 {
public static void main(String[] args) {
Stream<String> customers = Stream.of("Eric", "Tony", "Erica", "Daniel", "Sophia");
Consumer<String> eatHamburger = (customer) -> System.out.println(customer +" eats a hamburger");
customers.forEach(eatHamburger);
}
}
```

#### 3. 使用方法引用 Consumer
```java=
public class ConsumerDemo3 {
public static void main(String[] args) {
Stream<String> customers = Stream.of("Eric", "Tony", "Erica", "Daniel", "Sophia");
Consumer<String> eatHamburger = EatHamburger::eat;
customers.forEach(eatHamburger);
}
}
```
```java=
public class EatHamburger {
public static void eat(String customer) {
System.out.println(customer +" eats a hamburger");
}
}
```

以上方式都會執行 Consumer 方法的印出方式,讓 stream 內的每個元素執行 Consumer 內的方法。
#### Consumer 舉例使用
```java=
// forEach 就是使用 Consumer 介面的
void forEach(Consumer<? super T> action);
```
### Supplier 的實作過程
#### 1. 使用 Supplier 介面實現方法
```java=
public class SupplierDemo1 {
public static void main(String[] args) {
Supplier<Double> randomLuckyNumber = new Supplier<Double>() {
@Override
public Double get() {
return new Random().nextDouble();
}
};
System.out.println(randomLuckyNumber.get());
}
}
```

#### 2. 使用 lambda 實現 Supplier
```java=
public class SupplierDemo2 {
public static void main(String[] args) {
Supplier<Double> randomLuckyNumber = () -> new Random().nextDouble();
System.out.println(randomLuckyNumber.get());
}
}
```

#### 3. 使用方法引用 Supplier
```java=
public class SupplierDemo3 {
public static void main(String[] args) {
Supplier<Double> randomLuckyNumber = Math::random;
System.out.println(randomLuckyNumber.get());
}
}
```

以上的 Supplier 都可以得到一個隨機幸運數。
#### 4. 搭配 Stream 使用 Supplier
```java=
public class SupplierDemo4 {
public static void main(String[] args) {
Stream<Integer> stream = Stream.of(3,7,9);
Optional<Integer> first = stream.filter(i -> i > 11)
.findFirst();
Supplier<Integer> supplier = new Supplier<Integer>() {
@Override
public Integer get() {
return new Random().nextInt(10);
}
};
// orElseGet 如果 first 存在此數,就返回這個數字,如果不存在,就返回 supplier 的值
System.out.println(first.orElseGet(supplier));
}
}
```

#### Supplier 舉例使用
```java=
// collect 是使用 Supplier 的
<R> R collect(Supplier<R> supplier,
BiConsumer<R, ? super T> accumulator,
BiConsumer<R, R> combiner);
```
### Predicate 的實作過程
#### 1. 使用 Predicate 介面實現方法
```java=
public class PredicateDemo1 {
public static void main(String[] args) {
Predicate<Integer> integerBiggerThan5 = new Predicate<Integer>() {
@Override
public boolean test(Integer integer) {
if(integer > 5){
return true;
}
return false;
}
};
System.out.println(integerBiggerThan5.test(6));
}
```

#### 2. 使用 lambda 實現 Predicate
```java=
public class PredicateDemo2 {
public static void main(String[] args) {
Predicate<Integer> integerBiggerThan5 = (t) -> t > 5;
System.out.println(integerBiggerThan5.test(1));
}
}
```

以上都可以使用 Predicate 得到 Boolean。
#### 3. 搭配 Stream 使用 Predicate
```java=
public class PredicateDemo3 {
public static void main(String[] args) {
Predicate<Integer> numberBiggerThan5 = new Predicate<Integer>() {
@Override
public boolean test(Integer integer) {
if(integer > 5){
return true;
}
return false;
}
};
Stream<Integer> numbers = Stream.of(1, 23, 3, 4, 5, 56, 6, 6);
List<Integer> numbersBiggerThan5 = numbers.filter(numberBiggerThan5).collect(Collectors.toList());
numbersBiggerThan5.forEach(System.out::println);
}
}
```
可以得到所有大於 5 的數字。

#### Predicate 舉例使用
```java=
// filter 方法是使用 Predicate 的
Stream<T> filter(Predicate<? super T> predicate);
```
### Function 的實作過程
#### 1. 使用 Function 介面實現方法
```java=
public class FunctionDemo1 {
public static void main(String[] args) {
Function<String, Integer> lengthOfName = new Function<String, Integer>() {
@Override
public Integer apply(String s) {
return s.length();
}
};
Stream<String> names = Stream.of("Eric", "Allen", "Johny");
Stream<Integer> lengthOfNames = names.map(lengthOfName);
lengthOfNames.forEach(System.out::println);
}
}
```

印出 Stream 字串長度。

#### Function 舉例使用
```java=
// map 方法是使用 Function 的
<R> Stream<R> map(Function<? super T, ? extends R> mapper);
```
## 參考資料
[面试又挂了,你理解了 Java 8 的 Consumer、Supplier、Predicate和Function吗?](https://cloud.tencent.com/developer/article/1488128)