4

Java 8 には、プリミティブ ストリームでStream::collect(Collector)を使用する方法はありますか?

通常、Stream<Integer>例として、収集するための 2 つの方法があります。

ただしIntStream、収集する方法は 1 つだけです。

サンプルコードとして、次のものがあります。

@Override
public void run() {
    result = LongStream.range(1, maximum).boxed()
            .collect(Collectors.toMap(i -> i, i -> (int)Iterators.longStream(new CollatzGenerator(i)).count()))
            .entrySet().stream()
            .max(Comparator.comparingLong(Map.Entry::getValue))
            .get().getKey();
}

ご覧のとおり、メソッドを使用できるようにするために、最初にプリミティブをボックス化しますCollectors.

プリミティブを使用しても同じコードを使用できる方法はありますCollectors.toMap か?

4

2 に答える 2

4

Mapはジェネリック インターフェイスであるため、ボックス化せずに を作成する方法はありませんMapMapただし、別のストリームを作成することだけが必要な場合 ( a にラップされた 2 つの値のみ) 、アイテムを a に収集することはまったく意味がありませんMap.EntryMap.Entry値を収集せずにインスタンスを作成できます。

LongStream.range(1, maximum)
  .mapToObj(i->new AbstractMap.SimpleEntry<>(i, Iterators.longStream(new CollatzGenerator(i)).count()))
  .max(Comparator.comparingLong(Map.Entry::getValue))
  .get().getKey();

これはまだ自動ボクシングを行いますが、この時点でMap.Entry適切な値ホルダー クラスを自分で作成することで、自動ボクシングを取り除くことができます。

static final class TwoLongs {
    final long key, value;
    TwoLongs(long k, long v) { key=k; value=v; }
    public long getKey() { return key; }
    public long getValue() { return value; }
}

このホルダー クラスを使用すると、longsをボックス化せずにデータを処理できます。

LongStream.range(1, maximum)
  .mapToObj(i->new TwoLongs(i, Iterators.longStream(new CollatzGenerator(i)).count()))
  .max(Comparator.comparingLong(TwoLongs::getValue))
  .get().getKey();

まあ、それはまだある種のボクシングですが、3 つ (1 つと2 つの )TwoLongsではなく 1 つのアイテム (インスタンス) オブジェクトを作成します。Map.EntryLong

于 2014-02-25T18:36:13.257 に答える