为什么原始 Stream 没有 collect(Collector)? [英] Why don't primitive Stream have collect(Collector)?

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

问题描述

我正在为新手程序员编写一个库,因此我正在努力保持 API 尽可能干净.

I'm writing a library for novice programmers so I'm trying to keep the API as clean as possible.

我的库需要做的一件事是对大量整数或长整数执行一些复杂的计算.我的用户需要从很多场景和业务对象中计算这些值,所以我认为最好的方法是使用流来允许用户将业务对象映射到 IntStreamLongStream 然后计算收集器内部的计算.

One of the things my Library needs to do is perform some complex computations on a large collection of ints or longs. There are lots of scenarios and business objects that my users need to compute these values from, so I thought the best way would be to use streams to allow users to map business objects to IntStream or LongStream and then compute the computations inside of a collector.

但是 IntStream 和 LongStream 只有 3 个参数的 collect 方法:

However IntStream and LongStream only have the 3 parameter collect method:

collect(Supplier<R> supplier, ObjIntConsumer<R> accumulator, BiConsumer<R,R> combiner)

并且没有 Stream 具有的更简单的 collect(Collector) 方法.

And doesn't have the simplier collect(Collector) method that Stream<T> has.

所以,而不是能够做到

Collection<T> businessObjs = ...
MyResult result = businessObjs.stream()
                              .mapToInt( ... )
                              .collect( new MyComplexComputation(...));

我必须像这样提供供应商、累加器和组合器:

I have to do provide Suppliers, accumulators and combiners like this:

MyResult result = businessObjs.stream()
                              .mapToInt( ... )
                              .collect( 
                                  ()-> new MyComplexComputationBuilder(...),
                                  (builder, v)-> builder.add(v),
                                  (a,b)-> a.merge(b))
                              .build(); //prev collect returns Builder object

这对我的新手用户来说太复杂了,而且很容易出错.

This is way too complicated for my novice users and is very error prone.

我的工作是制作以 IntStreamLongStream 作为输入的静态方法,并为您隐藏收集器的创建和执行

My work around is to make static methods that take an IntStream or LongStream as input and hide the collector creation and execution for you

public static MyResult compute(IntStream stream, ...){
       return .collect( 
                        ()-> new MyComplexComputationBuilder(...),
                        (builder, v)-> builder.add(v),
                        (a,b)-> a.merge(b))
               .build();
}

但这不符合使用 Streams 的正常约定:

But that doesn't follow the normal conventions of working with Streams:

IntStream tmpStream = businessObjs.stream()
                              .mapToInt( ... );

 MyResult result = MyUtil.compute(tmpStream, ...);

因为您必须保存一个临时变量并将其传递给静态方法,或者在静态调用中创建 Stream,当它与我的计算的其他参数混合时可能会造成混淆.

Because you have to either save a temp variable and pass that to the static method, or create the Stream inside the static call which may be confusing when it's is mixed in with the other parameters to my computation.

在使用 IntStreamLongStream 的同时,是否有更简洁的方法来做到这一点?

Is there a cleaner way to do this while still working with IntStream or LongStream ?

推荐答案

我们实际上做了一些 Collector.OfXxx 专业化的原型.我们发现——除了更专业的类型的明显烦恼之外——如果没有完整的原始专业化集合(如 Trove 或 GS​​-Collections,但 JDK 确实如此),这并不是非常有用没有).例如,如果没有 IntArrayList,Collector.OfInt 只会将拳击推到其他地方——从收集器到容器——这没有什么大不了的,还有更多的 API 表面.

We did in fact prototype some Collector.OfXxx specializations. What we found -- in addition to the obvious annoyance of more specialized types -- was that this was not really very useful without having a full complement of primitive-specialized collections (like Trove does, or GS-Collections, but which the JDK does not have). Without an IntArrayList, for example, a Collector.OfInt merely pushes the boxing somewhere else -- from the Collector to the container -- which no big win, and lots more API surface.

这篇关于为什么原始 Stream 没有 collect(Collector)?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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