I'd like to have something like the following:
List<Something> list = ...;
new IndexStream(list).forEach(i, s -> System.println("Index: " i ". Something: " s));
I'm also ok with some mapping to pairs:
new IndexStream(list).forEach(pair -> System.println("Index: " pair.left() ". Something: " pair.right()));
Would also be nice if I could just wrap another stream and added the counting:
new IndexStream(anotherStream).forEach(pair -> System.println("Index: " pair.left() ". Something: " pair.right()));
Any idea how to achieve this? Perhaps there's a library for that?
CodePudding user response:
Using streams, IntStream.range(0, list.size()).forEach(i -> /* get element with list.get(i) */)
is the standard way to do this.
Your example is probably not everything that you're trying to do; but you could achieve what you've shown here using plain old loops, which are less restrictive than forEach
. For example, using an indexed for loop:
for (int i = 0; i < list.size(); i) {
Something e = list.get(i);
// ...
}
Or use an enhanced for loop, managing the index yourself:
int i = 0;
for (Something e : list) {
// ...
i ;
}
Or use a ListIterator
:
ListIterator<Something> lit = list.listIterator();
while (lit.hasNext()) {
int i = lit.nextIndex();
Something e = lit.next();
// ...
}
CodePudding user response:
You may simply use list.get(i)
to get the value:
List<Something> list = ...;
new IndexStream(list).forEach(i -> System.println("Index: " i ". Something: " list.get(i)));
CodePudding user response:
The conceptual problem is, that one does not actually want a named subclass of Stream.
public class IndexedStreams {
public static record IndexedValue<T>(int index, T value) { }
private final AtomicInteger counter = new AtomicInteger; // For (stream).
public static <T> Stream<IndexedValue> of(List<T> list) {
return IntStream.range(0, list.size)
.map(i -> new IndexedValue<T>(i, list.get(i));
}
public static <T> Stream<IndexedValue> of(Stream<T> stream) {
return stream.map(v -> new IndexedValue<T>(counter.getAnIncrement(), v));
}
}
Do not have a compiler at hand, so I am unsure about application of diamond <>
.
I am not sure whether java can do:
return stream.map(v -> new IndexedValue(counter.getAnIncrement(), v) {
private final AtomicInteger counter = new AtomicInteger;
};