LoginSignup
15
16

More than 5 years have passed since last update.

java8 の forEach を index つきで使いたい

Last updated at Posted at 2017-03-13

java8 の forEach メソッドを使う際、インデックス(連番)がほしい場合があります。そのとき、カウンタ変数を使おうとするとラムダ内で更新できないので、配列を使うなどしないといけません。

こうしたいができない
int i = 1;
java.util.stream.Stream.of("a", "b", "c", "d").forEach(s -> {
  System.out.println(i + ": " + s);
  i++;
});
こうならできる
int i[] = { 1 };
java.util.stream.Stream.of("a", "b", "c", "d").forEach(s -> {
  System.out.println(i[0] + ": " + s);
  i[0]++;
});

どちらにしても見通しがよくないので、こんな感じにしたい。

こうしたい
java.util.stream.Stream.of("a", "b", "c", "d").forEach(withIndex((s, i) -> System.out.println(i + ": " + s)));

ということで、ユーティリティメソッドを作ってあげます。

クラス名、メソッド名は適当
import java.util.function.Consumer;
import java.util.function.ObjIntConsumer;

public class With {
  public static <T> Consumer<T> B(int start, ObjIntConsumer<T> consumer) {
    int counter[] = { start };
    return obj -> consumer.accept(obj, counter[0]++);
  }
}

初期値も設定できるようにしました。

できた
java.util.stream.Stream.of("a", "b", "c", "d").forEach(With.B(1, (s, i) -> System.out.println(i + ": " + s)));
実行結果
1: a
2: b
3: c
4: d

[注意] streamで並列実行する場合は forEachOrdered を使う等工夫してください。

以上

15
16
3

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
15
16