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 を使う等工夫してください。
以上