我知道Stream.concat
存在(doc)以连接两个流。但是,我遇到了需要在现有流中添加“更多”项目,然后继续处理它的情况。在这种情况下,我本来希望能够将以下方法联系起来:
getStream(someArg)
.map(Arg::getFoo)
.concat(someOtherStreamOfFoos) // Or append, or...
.map(...)
但是,不存在此类实例级可链接append/concat
方法。
这不是一个问题,要求解决这个问题,或更优雅的方法(虽然我当然会感激任何其他观点!)。相反,我问的是导致这一决定的设计因素。我信任,Stream界面是由一些非常聪明的人设计的,他们都知道Principle of Least Astonishment - 所以,我必须假设他们决定省略这个(对我来说)直观明显的方法,这意味着方法是反模式,或由于某些技术限制而无法实现。我很想知道原因。
答案 0 :(得分:10)
我可以告诉你一个不起作用的原因。
Stream.concat
定义为
static <T> Stream<T> concat(Stream<? extends T> a,
Stream<? extends T> b)
您可以concat
Stream<HashMap>
和Stream<Map>
加入Stream<Map>
,甚至concat
加Stream<HashMap>
和Stream<TreeMap>
进入Stream<Map>
。要使用实例方法执行此操作,您需要能够声明类似<U super T>
的类型参数,而Java不允许这样做。
// It'd look kind of like this, if Java allowed it.
public <U super T> Stream<U> concat(Stream<? extends U> other)
Java只允许上限类型参数,而不是下限。
连接Stream<Something>
和Stream<SomethingElse>
可能看似不寻常,但类型推断通常会产生类型参数,这些参数太具体,无法使用实例方法。例如,
Stream.concat(Stream.of(dog), animalStream)
如果写为
,则需要显式类型参数Stream.<Animal>of(dog).concat(animalStream)
答案 1 :(得分:0)
我认为它只是错过了Stream API的功能。
请注意,RxJava的Observable具有所需功能的“concatWith”方法,因此您的问题是合理的:
Observable<String> o1 = ...;
Observable<Integer> o2 = ...;
o1.map(s -> s.length())
.concatWith(o2)
....
如果当前的Optional为空,那么Java 8还有另外一个功能就是获得另一个可选项,如:
Optional.ofNullable(x).orElse(anotherOptional)
我想说的是你所描述的这个结论是可能的,只是没有在Stream
中实现。