Java 8でインデックス付きのストリームを反復処理する簡潔な方法はありますか? 質問する

Java 8でインデックス付きのストリームを反復処理する簡潔な方法はありますか? 質問する

ストリーム内のインデックスにアクセスしながらストリームを反復処理する簡潔な方法はありますか?

String[] names = {"Sam","Pamela", "Dave", "Pascal", "Erik"};

List<String> nameList;
Stream<Integer> indices = intRange(1, names.length).boxed();
nameList = zip(indices, stream(names), SimpleEntry::new)
        .filter(e -> e.getValue().length() <= e.getKey())
        .map(Entry::getValue)
        .collect(toList());

これは、そこに示されているLINQの例と比較すると、かなり残念なようです。

string[] names = { "Sam", "Pamela", "Dave", "Pascal", "Erik" };
var nameList = names.Where((c, index) => c.Length <= index + 1).ToList();

もっと簡潔な方法はありますか?

さらに、ジッパーが移動したか削除されたようです...

ベストアンサー1

最もクリーンな方法は、インデックスのストリームから開始することです。

String[] names = {"Sam", "Pamela", "Dave", "Pascal", "Erik"};
IntStream.range(0, names.length)
         .filter(i -> names[i].length() <= i)
         .mapToObj(i -> names[i])
         .collect(Collectors.toList());

結果のリストには「Erik」のみが含まれます。


for ループに慣れている場合にもっと馴染みのある代替案としては、次のような可変オブジェクトを使用してアドホック カウンターを維持することが挙げられますAtomicInteger

String[] names = {"Sam", "Pamela", "Dave", "Pascal", "Erik"};
AtomicInteger index = new AtomicInteger();
List<String> list = Arrays.stream(names)
                          .filter(n -> n.length() <= index.incrementAndGet())
                          .collect(Collectors.toList());

後者の方法を並列ストリームで使用すると、アイテムが必ずしも「順番に」処理されないため、処理が失敗する可能性があることに注意してください。

おすすめ記事