きり丸の技術日記

技術検証したり、資格等をここに残していきます。

Javaのラムダ式(Stream API)でNullableな項目にCollectors.groupingByする

Javaのラムダ式(Stream API)にて、Collectors.groupingByというグルーピングしてくれるメソッドがあります。ただし、このメソッドの引数はNonNullである必要があり、万が一Nullが混ざってしまうとNullPointerException: element cannot be mapped to a null keyが発生してしまいます。

今回の記事では、Nullableな項目に対して、JavaのStream APIのCollectors.groupingByを実行する方法を記載します。

環境

  • Java
    • 17

対応

Optional.ofNullableメソッドを使用することで、対象の項目をnullではなく、Optional型に変換します。

param.stream().collect(Collectors.groupingBy(
    e -> Optional.ofNullable(e.author)
));

型がMap<Optional<String>, 対象クラス>になり、キーを取得する際に少々面倒にはなってしまいますが、分類分けをするには十分です。

テストコード

  public record Book(String id, String author) {

  }
  List<Book> param = List.of(
        new Book("1", "きり丸"),
        new Book("2", "きり丸"),
        new Book("3", "ゴリラ"),
        new Book("4", null)
    );

  @Test
  void test_01() {
    var actual = param.stream().collect(Collectors.groupingBy(
        e -> Optional.ofNullable(e.author)
    ));

    var expected = new HashMap<>();
    expected.put(Optional.of("きり丸"), List.of(
        new Book("1", "きり丸"),
        new Book("2", "きり丸")
    ));

    expected.put(Optional.of("ゴリラ"), List.of(
        new Book("3", "ゴリラ")
    ));
    expected.put(Optional.empty(), List.of(
        new Book("4", null)
    ));
    assertThat(actual).isEqualTo(expected);
  }

  @Test
  void test_02() {
    assertThatThrownBy(
        () -> param.stream().collect(Collectors.groupingBy(
            e -> e.author
        ))
    ).isInstanceOfSatisfying(NullPointerException.class,
        (e) -> assertThat(e.getLocalizedMessage()).isEqualTo("element cannot be mapped to a null key"));
  }

ソースコード

終わりに

この処理を知るまで、nullの場合は仮でダミー文言を入れ、あとで処理後にダミー文言をnullに変換しなおす作業を行っていました。

検索Wordさえ思いつけば簡単にヒットしますが、私の今後の備忘録のために残しておきます。

類似情報

参考情報