前々回から、Java SE 9の言語仕様や標準ライブラリの新機能を紹介しています。前回はjava.baseモジュールの中から、java.utilパッケージの新機能を解説しました。今回は、java.utilパッケージにも関連が深い「Project Lambda」の新機能について紹介します。

 Java SE 8のProject Lambdaでは、言語仕様の変更としてラムダ式、新しいライブラリとしてストリームが導入されました。前々回に紹介したように、Java SE 9ではラムダ式に関する言語仕様の変更はありません。その一方で、ストリームはさらに使いやすくなるように、メソッドの追加などが行われています。

ストリームにファクトリーメソッドが追加

 ストリームには、以下の2つのファクトリーメソッドが追加されました。

  • ofNullable
  • iterate

 ofNullableメソッドはStreamインタフェースだけ、iterateメソッドはすべてのストリームで使用できます。iterateメソッドはJava SE 8からあったはずと思われる方もいらっしゃるかもしれません。それは正しい認識です。Java SE 9ではiterateメソッドのオーバーロードが追加されたのです。

ofNullableメソッド

 では、ofNullableメソッドから解説しましょう。ofNullableメソッドは引数を1つだけ取るファクトリーメソッドです。既存のofメソッドは可変長引数ですが、ofNullableメソッドは可変長引数ではありません。また、メソッド名から分かるように引数がnullであることも許容します。

 しかし、なぜこのようなファクトリーメソッドが必要なのでしょうか。その答えはストリームのパイプライン処理中に使用することにあります。

 例えば、nullが返るかもしれないgetValueメソッドを中間操作に使用することを考えてみます。もし、nullが返ってきた時は、それを無視して次の要素に進むようにするとしましょう。

 Java SE 8までであれば、リスト1のように記述できます。

リスト1●nullを返すかもしれないメソッドを使用する例(Java SE 8)。終端処理は省略。

List<String> contents = ...;

contents.stream()
        .flatMap(c -> {
            String value = getValue(c);
            return value != null? Stream.of(value): Stream.empty();
        })
        ...;

 mapメソッドではなくflatMapメソッドを使用しているのは、mapメソッドだとgetValueメソッドの返り値がnullの場合、次の処理にnullが渡ってしまうからです。flatMapメソッドを使用し、nullの場合には空のストリームを返すようにすれば、次の処理にnullが渡ることはありません。しかし、このような場合、Java SE 8ではnullかどうかの三項演算子もしくはif文が必要になってしまいます。

 このような場合に有効なのがofNullableメソッドです。ofNullableメソッドを使用してリスト1を書きかえたのが、リスト2です。

リスト2●nullを返すかもしれないメソッドを使用する例(Java SE 9)

List<String> contents = ...;

contents.stream()
        .flatMap(c -> Stream.ofNullable(getValue(c)))
        ...;

 赤字で示したように、ofNullableメソッドを使用すると、条件文を削除できるのです。