1. ホーム
  2. java

[解決済み] Java 8でインデックスを持つストリームを反復処理する簡潔な方法はありますか?

2022-03-22 21:26:48

質問

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

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();

もっと簡潔な方法はないのでしょうか?

さらにZIPが移動したか、削除されたようです...。

解決方法は?

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

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ループに慣れている人なら、より馴染みやすい方法として、mutableオブジェクトを使用してアドホックカウンターを維持することができます。 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());

注意点 を並列ストリームで使用すると、アイテムが必ずしも "順番に処理されないため、破損する可能性があります。 .