简体   繁体   English

为什么Java中没有实例级的Stream.concat方法?

[英]Why is there no Instance-level Stream.concat method in Java?

I know that Stream.concat exists ( doc ) to concatenate two streams. 我知道Stream.concat存在( doc )来连接两个流。 However, I have run into cases where I need to add "a few more" items to an existing stream, and then continue processing on it. 但是,我遇到了需要在现有流中添加“更多”项目,然后继续处理它的情况。 In such a situation, I would have expected to be able to chain together methods like: 在这种情况下,我本来希望能够将以下方法联系在一起:

getStream(someArg)
  .map(Arg::getFoo)
  .concat(someOtherStreamOfFoos) // Or append, or...
  .map(...)

However, no such instance-level chainable append/concat method exists. 但是,不存在这种实例级可链接的append/concat方法。

This isn't a question asking for solutions to this problem, or more elegant approaches (although I would of course be grateful for any other viewpoints!). 这不是一个问题,要求解决这个问题,或更优雅的方法(虽然我当然会感激任何其他观点!)。 Rather, I'm asking about the design factors that led to this decision. 相反,我问的是导致这一决定的设计因素。 The Stream interface was, I trust, designed by some extremely smart people who are aware of the Principle of Least Astonishment - so, I must assume that their decision to omit this (to me) intuitively-obvious method signifies either that the method is an antipattern, or that it is not possible due to some technical limitation. 我信任,Stream界面是由一些非常聪明的人设计的,他们都知道最小惊讶原则 - 所以,我必须假设他们决定省略这个(对我而言)直观明显的方法,这意味着该方法是一个反模式,或由于某些技术限制而无法实现。 I'd love to know the reason. 我很想知道原因。

I can give you one reason it wouldn't have worked. 我可以给你一个不起作用的理由。

Stream.concat is defined as Stream.concat定义为

static <T> Stream<T> concat(Stream<? extends T> a,
                            Stream<? extends T> b)

You can concat a Stream<HashMap> and Stream<Map> into a Stream<Map> , or even concat a Stream<HashMap> and a Stream<TreeMap> into a Stream<Map> . 您可以concat一个Stream<HashMap>Stream<Map>Stream<Map> ,甚至concat一个Stream<HashMap>Stream<TreeMap>Stream<Map> To do that with an instance method, you would need to be able to declare a type parameter like <U super T> , which Java doesn't allow. 要使用实例方法执行此操作,您需要能够声明类型参数,如<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 only allows upper-bounded type parameters, not lower-bounded. Java只允许上限类型参数,而不是下限。

Concatenating a Stream<Something> and a Stream<SomethingElse> might seem unusual, but type inference often produces type parameters too specific to work with an instance method. 连接Stream<Something>Stream<SomethingElse>可能看起来很不寻常,但类型推断通常会生成特定的类型参数,无法使用实例方法。 For example, 例如,

Stream.concat(Stream.of(dog), animalStream)

which would require an explicit type parameter if written as 如果写成,则需要显式类型参数

Stream.<Animal>of(dog).concat(animalStream)

I think it is just missed functionality of Stream API. 我认为它只是错过了Stream API的功能。

Note that RxJava's Observable has method "concatWith" with required functionality, so your question is reasonable: 请注意,RxJava的Observable具有所需功能的“concatWith”方法,因此您的问题是合理的:

Observable<String> o1 = ...;
Observable<Integer> o2 = ...;
o1.map(s -> s.length())
  .concatWith(o2)
  ....

Java 8 has another functionality is nice to have is get another Optional if current Optional is empty, like: 如果当前的Optional为空,Java 8还有另一个很好的功能就是获取另一个可选项,如:

Optional.ofNullable(x).orElse(anotherOptional)

What I want to say that this concat you described is possible, just not implemented in the Stream . 我想说的是你所描述的这个结论是可能的,只是没有在Stream实现。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM