Is there a concise way to iterate over a stream whilst having access to the index in the stream?
String[] names = {\"Sam\",\"Pamela\", \"Dave\", \"Pascal\",
You can use IntStream.iterate() to get the index:
String[] names = {"Sam","Pamela", "Dave", "Pascal", "Erik"};
List<String> nameList = IntStream.iterate(0, i -> i < names.length, i -> i + 1)
.filter(i -> names[i].length() <= i)
.mapToObj(i -> names[i])
.collect(Collectors.toList());
This only works for Java 9 upwards in Java 8 you can use this:
String[] names = {"Sam","Pamela", "Dave", "Pascal", "Erik"};
List<String> nameList = IntStream.iterate(0, i -> i + 1)
.limit(names.length)
.filter(i -> names[i].length() <= i)
.mapToObj(i -> names[i])
.collect(Collectors.toList());
Here is code by AbacusUtil
Stream.of(names).indexed()
.filter(e -> e.value().length() <= e.index())
.map(Indexed::value).toList();
Disclosure: I'm the developer of AbacusUtil.
Since guava 21, you can use
Streams.mapWithIndex()
Example (from official doc):
Streams.mapWithIndex(
Stream.of("a", "b", "c"),
(str, index) -> str + ":" + index)
) // will return Stream.of("a:0", "b:1", "c:2")
There isn't a way to iterate over a Stream
whilst having access to the index because a Stream
is unlike any Collection
. A Stream
is merely a pipeline for carrying data from one place to another, as stated in the documentation:
No storage. A stream is not a data structure that stores elements; instead, they carry values from a source (which could be a data structure, a generator, an IO channel, etc) through a pipeline of computational operations.
Of course, as you appear to be hinting at in your question, you could always convert your Stream<V>
to a Collection<V>
, such as a List<V>
, in which you will have access to the indexes.