Optional, null, empty

Optionalまわりの備忘録.

# バージョン情報
* Java 1.8

```xml:pom.xml
<dependency>
	<groupId>junit</groupId>
	<artifactId>junit</artifactId>
	<version>4.12</version>
</dependency>
<dependency>
	<groupId>org.hamcrest</groupId>
	<artifactId>hamcrest-all</artifactId>
	<version>1.3</version>
</dependency>
```

# テストコード
```java:src/test/java/sandbox/OptionalTest.java
package sandbox;

import java.util.Optional;

import org.junit.Test;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.MatcherAssert.assertThat;

public class OptionalTest {
    @Test
    public void testMap() {
        Optional<?> optional;

        // ofNullable() に null を渡すと empty になる.
        // of() で null を渡すと例外が飛ぶので気をつけよう.
        optional = Optional.ofNullable(null);
        assertThat(optional, is(Optional.empty()));

        // map() の中で null を返されると, map() の戻り値は empty になる.
        optional = Optional.of("llama")
            .map(string -> null);
        assertThat(optional, is(Optional.empty()));

        // empty に対する map() は何もせず, ただ empty を返す.
        optional = Optional.empty()
            .map(none -> "llama");
        assertThat(optional, is(Optional.empty()));

        // 途中で empty が現れても安心.
        optional = Optional.of("vicuguna")
            .map(string -> null)
            .map(none -> "llama");
        assertThat(optional, is(Optional.empty()));
    }

    @Test
    public void testFlatMap() {
        Optional<?> optional;

        // of() に empty を渡しても, 生の empty にはならない.
        optional = Optional.of(Optional.empty());
        assertThat(optional, is(Optional.of(Optional.empty())));

        // map() 内で Optional を返されると, Optional で二重に包まれる.
        optional = Optional.of("alpaca")
            .map(string -> Optional.of(string));
        assertThat(optional, is(Optional.of(Optional.of("alpaca"))));

        optional = Optional.of("llama")
            .map(string -> Optional.empty());
        assertThat(optional, is(Optional.of(Optional.empty())));

        // 二重 Optional を回避するには, flatMap() を使う.
        optional = Optional.of("alpaca")
            .flatMap(string -> Optional.of(string));
        assertThat(optional, is(Optional.of("alpaca")));

        optional = Optional.of("llama")
            .flatMap(string -> Optional.empty());
        assertThat(optional, is(Optional.empty()));

        // empty に対する flatMap() は, map() と同様に何もせず, ただ empty を返す.
        optional = Optional.empty()
            .flatMap(none -> Optional.of("llama"));
        assertThat(optional, is(Optional.empty()));
    }

    @Test
    public void testOrElse() {
        Object value;

        // Optional の中身が欲しいときは get() する.
        // ただし, この Optional は empty であってはならない.
        value = Optional.of("alpaca")
            .get();
        assertThat(value, is("alpaca"));

        // Optional の中身が empty かもしれないときは orElse() を使う.
        value = Optional.of("alpaca")
            .orElse("llama");
        assertThat(value, is("alpaca"));

        value = Optional.empty()
            .orElse("alpaca");
        assertThat(value, is("alpaca"));

        // orElseGet() を使うと Supplier#get から値を引いてこれる
        value = Optional.empty()
            .orElseGet(() -> "alpaca");
        assertThat(value, is("alpaca"));

        // 途中で empty が現れても安心.
        value = Optional.of("vicuguna")
            .map(string -> null)
            .map(none -> "llama")
            .orElse("alpaca");
        assertThat(value, is("alpaca"));
    }
}
```