LoginSignup
3
0

More than 5 years have passed since last update.

Java8 Stream.mapでindexをつける(タプル版)

Posted at

前置き

i02302さんのJava8以降のStream.mapでindexをつけるでStreamの各要素にindexを付加する方法が書かれていました。

最初に見たときはindexのカウンターに配列を使っていて、並列Streamも考慮してAtomicIntegerにした方がいいんじゃないかな…と思っていましたが、さっき見たらそう変わっていました(笑)

あとは、intのindex部分がBiFuntionを使うとIntegerになってしまうので、関数型インターフェースも独自に用意した方がよいのではないかと思います。

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のzipWithIndexだと要素とインデックスのペア(タプル)を返すので、それと同様にする方法もあると思います。

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())
3
0
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
0