【问题标题】:Using a Collector on a primitive stream在原始流上使用收集器
【发布时间】:2014-10-03 11:47:47
【问题描述】:

在 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 相同的代码 ?

【问题讨论】:

  • 既然地图无论如何都会包含对象,那有什么好处呢?

标签: java java-8 primitive boxing java-stream


【解决方案1】:

由于Map 是一个通用接口,没有装箱就无法创建Map。但是,如果您只想创建另一个流(Map.Entry 中只包含两个值),那么将项目收集到 Map 中根本没有意义。您可以只创建 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; }
}

有了这个持有者类,你可以处理你的数据而不用装箱longs:

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 和两个 Longs)。

【讨论】:

  • 这仍然比它必须的复杂。
  • 你的意思是,Java 8 中有更简单的方法,还是应该有更简单的方法,例如 Java 提供元组,或者更简单的方法来生成有限流?
  • @Stuart Marks:他指的是将第二个值的逻辑集成到Comparator 函数中的可能性。所以不需要映射到流内的一种 pair 但缺点是Comparator 会比必要的更频繁地计算值。因此,对于简单的映射,它可以简化代码,但对于这种用例,不推荐使用。我认为他出于这个原因撤销了他的回答。
  • 谢谢,我错过了另一个答案。
【解决方案2】:
long result = LongStream.range(0, 9)
        .mapToObj(i -> new long[]{i, i})
        .max(Comparator.comparingLong(pair -> pair[1]))
        .get()[0];

【讨论】:

    猜你喜欢
    • 2015-07-30
    • 2020-09-02
    • 1970-01-01
    • 2022-11-19
    • 1970-01-01
    • 2014-01-26
    • 1970-01-01
    • 2022-09-22
    • 1970-01-01
    相关资源
    最近更新 更多