为什么Collectors.toList()不能处理原始集合? [英] Why doesn't Collectors.toList() work on primitive collections?

查看:210
本文介绍了为什么Collectors.toList()不能处理原始集合?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

(这可能与 https://stackoverflow.com/a/30312177/160137 有关,但我'我担心我仍然没有得到它。所以我这样问我的问题,希望它会导致我更容易理解的答案。)

(This is probably related to https://stackoverflow.com/a/30312177/160137, but I'm afraid I still don't get it. So I'm asking my question this way, in the hope that it'll lead to an answer I can more easily understand.)

通常当我有一个Stream时,我可以使用Collectors类中的一个静态方法将它转换为一个集合:

Normally when I have a Stream I can convert it to a collection using one of the static methods in the Collectors class:

List<String> strings = Stream.of("this", "is", "a", "list", "of", "strings")
    .collect(Collectors.toList());

类似的过程不适用于原始流,但正如其他人注意到的那样:

The similar process doesn't work on primitive streams, however, as others have noticed:

IntStream.of(3, 1, 4, 1, 5, 9)
    .collect(Collectors.toList());  // doesn't compile

我可以这样做:

IntStream.of(3, 1, 4, 1, 5, 9)
    .boxed()
    .collect(Collectors.toList());

或者我可以这样做:

IntStream.of(3, 1, 4, 1, 5, 9)
    .collect(ArrayList<Integer>::new, ArrayList::add, ArrayList::addAll);

问题是,为什么Collectors.toList()只对原始流执行此操作?难道没有办法指定包装类型吗?如果是这样,为什么这不起作用:

The question is, why doesn't Collectors.toList() just do that for primitive streams? Is it that there's no way to specify the wrapped type? If so, why doesn't this work either:

IntStream.of(3, 1, 4, 1, 5, 9)
    .collect(Collectors.toCollection(ArrayList<Integer>::new)); // nope

任何见解都将受到赞赏。

Any insight would be appreciated.

推荐答案

好吧,让 IntStream 提供带签名的方法是没有问题的?
< R,A> R collect(Collector<?super Integer,A,R> collector)执行隐式装箱。它可以简单地实现为返回boxed()。collect(collector);

Well, it would be no problem to let IntStream provide a method with the signature
<R,A> R collect(Collector<? super Integer,A,R> collector) performing an implicit boxing. It could be implemented as simple as return boxed().collect(collector);.

问题是它为什么要或者反过来:为什么原始流特化存在呢?

The question is "why should it" or the other way round: why do the primitive stream specializations exist at all?

它们仅仅出于性能原因而存在,提供没有装箱开销的流操作。因此,显而易见的设计决定是不包括通用 Stream 接口中已存在的任何操作,因为所有这些操作都可以简单地调用 boxed()。 genericOperation(...)

They merely exist for performance reasons, to offer stream operations without boxing overhead. So it’s an obvious design decision not to include any operation which already exists in the generic Stream interface as for all these you can simply invoke boxed().genericOperation(…).

答案,您已链接地址相关但不同的想法。它是关于提供一个 collect 方法,不接受泛型收集器,但是一个原始的特化,如收集器.ofInt 可以在没有装箱的情况下收集 int 值,但是对于产生 List< Integer> ,不可避免地包含盒装值,它没有任何好处。
在预建的收藏家中,只有少数人真的可以避免拳击。所有这些都作为原始流的显式终端操作提供( count() sum() min() max() summaryStatistics(),... )

The answer, you have linked addresses a related, but different idea. It’s about providing a collect method not accepting the generic Collector, but a primitive specialization like Collector.ofInt which could collect int values without boxing, but for a collector which produces a List<Integer>, unavoidably containing boxed values, it wouldn’t have any benefit. Amongst the prebuilt collectors, only a few really could avoid boxing. All of them are provided as explicit terminal operations on the primitive streams (count(), sum(), min(), max(), summaryStatistics(), …)

这是类/接口数量和潜在性能增益之间的权衡。对于一般的流,决定创建 IntStream LongStream DoubleStream ,但在收藏家的情况下,决定不添加此类专业化。

It’s a trade-off between number of classes/interfaces and potential performance gain. In the case of streams in general, the decision was to create IntStream, LongStream and DoubleStream, but in case of the collectors, the decision was not to add such specializations.

这篇关于为什么Collectors.toList()不能处理原始集合?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆