4

Java 8 中是否有任何方法可以在原始流上使用Stream::collect(Collector) ?

通常Stream<Integer>作为示例有两种收集方法:

但是IntStream只有一种收集方法:

现在作为示例代码,我有以下内容:

@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是通用接口,因此无法创建Map没有装箱的接口。Map但是,当您只想创建另一个流(只有两个值包含在 a 中)时,将项目收集到 a 中根本没有意义Map.Entry。您可以只创建Map.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; }
}

使用这个持有者类,您可以在不装箱的情况下处理您的数据long

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

好吧,它仍然是某种装箱,但创建一个项目(TwoLongs实例)对象而不是三个(一个Map.Entry和两个Long)。

于 2014-02-25T18:36:13.257 回答
0
long result = LongStream.range(0, 9)
        .mapToObj(i -> new long[]{i, i})
        .max(Comparator.comparingLong(pair -> pair[1]))
        .get()[0];
于 2014-10-03T03:40:59.933 回答