mike-neckのブログ

Java or Groovy or Swift or Golang

いまさら聞けないOptionalIntのまとめ

こんにちわ、みけです。

表題の通り、いまさらOptionalIntって何って人に聞けなかったので、

自分で試してみました。


まずはテスト内でこれらの値を準備しておきます。

    private final OptionalInt value = OptionalInt.of(1);

    private final OptionalInt empty = OptionalInt.empty();

以後、

  • valueが出てきたら1の入っている奴、
  • emptyが出てきたら何も入ってない奴

だと思って下さい。

public boolean isPresent ()

値が入っていればtrue、入っていなければfalseが返ってきます。

    @Test
    public void 値があるものに対してisPresentを使うとtrue () {
        assertThat(value.isPresent(), is(true));
    }

    @Test
    public void 値がないものに対してisPresentを使うとfalse () {
        assertThat(empty.isPresent(), is(false));
    }

public int getAsInt()

値が入っていればその値、入ってなければNoSuchElementExceptionが投げられます。

    @Test
    public void 値があるものにgetAsIntするとその値が取得できる () {
        assertThat(value.getAsInt(), is(1));
    }

    @Test (expected = NoSuchElementException.class)
    public void 値がないものにgetAsIntするとNoSuchElementException () {
        empty.getAsInt();
    }

public void ifPresent (java.util.function.IntConsumer)

値が入っていればIntConsumerが実行されます。

値がない場合は、実行されません。

    @Test
    public void 値があるものに対してifPresentするとConsumerが呼ばれる () {
        value.ifPresent(it -> assertThat(it, is(1)));
    }

    @Test
    public void 値がないものに対してifPresentするとConsumerは呼ばれない () {
        empty.ifPresent(it -> fail(it + " can't be used here."));
    }

public int orElse (int)

値が入っていればその値が返されます。

値がない場合は引数の値が返されます。

    @Test
    public void 値があるものに対してorElseしても元の値が返される () {
        int actual = value.orElse(100);
        assertThat(actual, is(1));
    }

    @Test
    public void 値がないものに対してorElseすると与えられた値が返される () {
        int actual = empty.orElse(100);
        assertThat(actual, is(100));
    }

public int orElseGet (java.util.function.IntSupplier)

値が入っていればその値が返されます。

値がなければIntSupplierによって生成される値が返ってきます。

    @Test
    public void 値があるものに対してorElseGetしてもSupplierは呼び出されない () {
        int actual = value.orElseGet(() -> {
            fail("ここは通過しない");
            return 100;
        });
        assertThat(actual, is(1));
    }

    @Test
    public void 値がないものに対してorEleseGetするとSupplierによって提供される値が取得される () {
        int actual = empty.orElseGet(() -> 100);
        assertThat(actual, is(100));
    }

public int orElseThrow (java.util.function.Supplier)

値が入っていればその値が返されます。

値が入っていない場合には、Supplierによって生成される例外が投げられます。

    @Test
    public void 値があるもの対してorElseThrowしても例外は発生しない () {
        int actual = value.orElseThrow(() -> new TestException("発生しない"));
        assertThat(actual, is(1));
    }

    @Test (expected = TestException.class)
    public void 値がないものに対してorElseThrowするとExceptionSupplierが呼ばれて例外が発生する () {
        empty.orElseThrow(() -> new TestException("発生するべき"));
        fail("ここまでは来ない");
    }

    public static class TestException extends RuntimeException {
        TestException (String message) {
            super(message);
        }
    }

さて、OptionalIntjavadocを見ていると妙な一文があります。

This is a value-based class; use of identity-sensitive operations (including reference equality (==), identity hash code, or synchronization) on instances of OptionalInt may have unpredictable results and should be avoided.

直訳すると、同一性に関する操作をOptionalIntに行うのはやめたほうがよいとのことです。

次のような操作は避けたほうが良さそうです。

    @Ignore
    @Test
    public void equality () {
        OptionalInt one = OptionalInt.of(1);
        assertThat(value == one, is(true));
    }

明後日くらいはIntStreamをやると思う。