Java
java8
Java9

Java8以降のStream.mapでindexをつける


Stream.mapindex つけたい


  • 並列処理だから index の数字の順序に意味はなさそう

  • でも使えたらテストデータとかをぱっと作るのに便利になりそう


  • forEach はいい感じの記事見つけたけど、mapは見つからなかったからつくった(つくらなくてもできたりするのかな?)


参考にした記事

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


たとえばこのEntityStreamをかんたんにつくりたいとき


テストデータ用のEntityクラス.java

class TestEntity {

Integer id;
String name;
}


mapindexつけれないと、こんな感じで書くしかないような・・・


めんどい.java

// 元のデータ

Stream<String> stream = Stream.of("taro", "jiro", "saburo");

List<TestEntity> testDataList = List.of();
List<String> list = stream.collect(Collectors.toList());
int index = 1;
for (String name : list) {
testDataList.add(TestEntity.builder().id(index).name(name).build());
index++;
}
Stream<TestEntity> testDataStream = testDataList.stream();



こっちのほうが楽


【追記】コメントでパラレルストリームのときにカウンタが排他制御されてなくて競合するとご指摘いただいたので、カウンタをint ---> AtomicIntegerに変更してみました。


ユーティリティ.java


import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.BiFunction;
import java.util.function.Function;

public class With {

public static <T, R> Function<T, R> idx(int start, BiFunction<T, Integer, R> function) {
AtomicInteger counter = new AtomicInteger(start - 1);
return obj -> function.apply(obj, counter.addAndGet(1));
}

}



らくちん.java

// 元のデータ

Stream<String> stream = Stream.of("taro", "jiro", "saburo");

Stream<TestEntity> testDataStream = stream.map(With.idx(1, (name, i) -> TestEntity.builder().id(i).name(name).build()));