i02302's Add index with Stream.map after Java8 described how to add index to each element of Stream.
When I first saw it, I was using an array for the index counter, and I thought it would be better to use an atomic Integer in consideration of parallel Streams ... but when I saw it earlier, it changed so (laughs).
After that, if you use BiFuntion, the index part of int will be Integer, so I think it is better to prepare your own functional interface.
public interface BiIntFunction<T, R> {
public R apply(T t, int n);
}
public class WithIndex {
public static <T, R> Function<T, R> apply(int start, BiIntFunction<T, R> function) {
AtomicInteger counter = new AtomicInteger(start);
return object -> function.apply(object, counter.getAndAdd(1));
}
}
stream.map(WithIndex.apply(1, (obj, i) -> obj + i))
Scala's zipWithIndex returns an element-index pair (tuple), so it's the same. I think there is also a way to do it.
public class ObjectIndexPair<T> {
private final T object;
private final int index;
private ObjectIndexPair(T object, int index) {
this.object = object;
this.index = index;
}
public T getObject() {
return object;
}
public int getIndex() {
return index;
}
public static <T> Function<T, ObjectIndexPair<T>> start(int start) {
AtomicInteger counter = new AtomicInteger(start);
return object -> new ObjectIndexPair<>(object, counter.getAndAdd(1));
}
}
stream.map(ObjectIndexPair.start(1)).map(pair -> pair.getObject() + pair.getIndex())
Recommended Posts