LoginSignup
1
1

More than 3 years have passed since last update.

Java9から追加されたStreamクラスのiterateメソッドの第三引数でインクリメント

Last updated at Posted at 2020-11-02

概要

本記事はJava9から追加されたStreamクラスのiterateメソッドの第三引数でインクリメントした際の挙動についてまとめたものです。

1.Streamクラスの入力引数を三つ持つiterateメソッドについて

Streamクラスの入力引数を三つ持つiterateメソッドの使い方として、以下のようなコードで紹介されるのをよくお見かけします。

Stream.iterate使い方のサンプルコード
// 0~9までの数値を出力するコード
Stream.iterate(0, i -> i < 10, i -> i + 1).forEach(System.out::println);
実行結果
0
1
2
3
4
5
6
7
8
9

iterateメソッドの引数はそれぞれ以下の通りです。
第一引数:初期値
第二引数:次のStreamの要素を返すための条件を返却するクラス(サンプルコード上はラムダ式で記載)
第三引数:次のStreamの要素を返却するクラス(サンプルコード上はラムダ式で記載)
従来のfor文に書き直すと以下のようになります。

サンプルコードを従来のfor文に書き直したコード
for (int i = 0; i < 10; i++) {
     System.out.println(i);
}

初めて知った当時はStream APIでfor文ライクなものが使えると感動しました。

JavaのAPIドキュメントは以下のリンク先です。
JavaのAPIドキュメントよりStream.iterateの仕様

2.第三引数でのインクリメント

第三引数についてインクリメントを使わずにi->i+1でよく説明されることについて疑問に思い、以下のような記載をしました。

サンプルコードの第三引数を書きかえたコード?
Stream.iterate(0, i -> i < 10, i -> i++).forEach(System.out::println);

すると実行結果は以下のようになりました。

実行結果
0
0
0
0
0
0
0
0
~~~~~~~~~~~~~~~~~~~~~~
以下、延々と0が出力され続けるため省略
~~~~~~~~~~~~~~~~~~~~~~

i=0のまま結果が出力されることになり、無限ループが発生します。
Stream.classで第三引数に指定したUnaryOperatorクラスのapplyメソッド(サンプルコード上ではラムダ式で記載)を利用しているため、第三引数で値をインクリメントする前に返却してるのですね。
どうしてもインクリメントにしたい場合は以下のように後置から前置に書き直す必要があります。

サンプルコードの第三引数を書きかえたコード
Stream.iterate(0, i -> i < 10, i -> ++i).forEach(System.out::println);

おわりに

インクリメントについてこのような特徴があるから紹介するときはi->i+1で書いてるのかもしれませんね。
個人的に書く場合はインクリメント使いそうです。
そもそも私は9以降のJavaについて個人でしか使ってませんが……

1
1
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
1
1