5
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Optional, null, empty

Last updated at Posted at 2015-10-01

Optionalまわりの備忘録.

バージョン情報

  • Java 1.8
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>

テストコード

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"));
    }
}
5
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?