# 內置函數式接口
JDK 1.8 API中包含了很多內置的函數式接口。有些是在以前版本的Java中大家耳熟能詳的,例如Comparator接口,或者Runnable接口。對這些現成的接口進行實現,可以通過@FunctionalInterface 標注來啟用Lambda功能支持。
此外,Java 8 API 還提供了很多新的函數式接口,來降低程序員的工作負擔。有些新的接口已經在[Google Guava](https://code.google.com/p/guava-libraries/)庫中很有名了。如果你對這些庫很熟的話,你甚至閉上眼睛都能夠想到,這些接口在類庫的實現過程中起了多么大的作用。
#### Predicates
Predicate是一個布爾類型的函數,該函數只有一個輸入參數。Predicate接口包含了多種默認方法,用于處理復雜的邏輯動詞(and, or,negate)
```
Predicate<String> predicate = (s) -> s.length() > 0;
predicate.test("foo"); // true
predicate.negate().test("foo"); // false
Predicate<Boolean> nonNull = Objects::nonNull;
Predicate<Boolean> isNull = Objects::isNull;
Predicate<String> isEmpty = String::isEmpty;
Predicate<String> isNotEmpty = isEmpty.negate();
```
#### Functions
Function接口接收一個參數,并返回單一的結果。默認方法可以將多個函數串在一起(compse, andThen)
```
Function<String, Integer> toInteger = Integer::valueOf;
Function<String, String> backToString = toInteger.andThen(String::valueOf);
backToString.apply("123"); // "123"
```
#### Suppliers
Supplier接口產生一個給定類型的結果。與Function不同的是,Supplier沒有輸入參數。
```
Supplier<Person> personSupplier = Person::new;
personSupplier.get(); // new Person
```
#### Consumers
Consumer代表了在一個輸入參數上需要進行的操作。
```
Consumer<Person> greeter = (p) -> System.out.println("Hello, " + p.firstName);
greeter.accept(new Person("Luke", "Skywalker"));
```
#### Comparators
Comparator接口在早期的Java版本中非常著名。Java 8 為這個接口添加了不同的默認方法。
```
Comparator<Person> comparator = (p1, p2) -> p1.firstName.compareTo(p2.firstName);
Person p1 = new Person("John", "Doe");
Person p2 = new Person("Alice", "Wonderland");
comparator.compare(p1, p2); // > 0
comparator.reversed().compare(p1, p2); // < 0
```
#### Optionals
Optional不是一個函數式接口,而是一個精巧的工具接口,用來防止NullPointerEception產生。這個概念在下一節會顯得很重要,所以我們在這里快速地瀏覽一下Optional的工作原理。
Optional是一個簡單的值容器,這個值可以是null,也可以是non-null。考慮到一個方法可能會返回一個non-null的值,也可能返回一個空值。為了不直接返回null,我們在Java 8中就返回一個Optional.
```
Optional<String> optional = Optional.of("bam");
optional.isPresent(); // true
optional.get(); // "bam"
optional.orElse("fallback"); // "bam"
optional.ifPresent((s) -> System.out.println(s.charAt(0))); // "b"
```