Java 8 流和可变参数
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/36437483/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Java 8 streams and varargs
提问by Paul Nelson Baker
According to Effective Java 2nd Ed, when you want to write a method signature that allows for varargs but still enforces that you have one element minimum at compile-time you should write the method signature this way:
根据Effective Java 2nd Ed,当您想编写允许可变参数但仍强制要求在编译时最少有一个元素的方法签名时,您应该这样编写方法签名:
public void something(String required, String ... additional) {
//... do what you want to do
}
If I want to stream all these elements, I've been doing something like this:
如果我想流式传输所有这些元素,我一直在做这样的事情:
public void something(String required, String ... additional) {
Stream<String> allParams =
Stream.concat(Stream.of(required), Stream.of(additional));
//... do what you want to do
}
This feels really inelegant and wasteful, especially because I'm creating a stream of 1 and concatenating it with another. Is there a cleaner way to do this?
这感觉真的很不优雅和浪费,特别是因为我正在创建一个 1 的流并将它与另一个连接起来。有没有更干净的方法来做到这一点?
采纳答案by Sleiman Jneidi
Here is a way for doing it without creating two Streams
, although you might not like it.
这是一种无需创建两个即可完成此操作的方法Streams
,尽管您可能不喜欢它。
Stream.Builder<String> builder = Stream.<String>builder().add(required);
for (String s : additional) {
builder.add(s);
}
Stream<String> allParams = builder.build();
回答by user140547
Unfortunately, Java can be quite verbose. But another option to alleviate that is to simply use static imports. In my opinion, it does not make your code less clear since every method is stream-related.
不幸的是,Java 可能非常冗长。但是另一个缓解这种情况的选择是简单地使用静态导入。在我看来,它不会使您的代码不那么清晰,因为每个方法都与流相关。
Stream<String> allParams =
concat(of(required), of(additional));
回答by Holger
There is nothing wrong with the composed streams. These objects are lightweight as they only refer to the source data but don't copy data like array contents. The cost of such lightweight object might only be relevant if the actual payload is very small as well. Such scenarios can be handled with specialized, semantically equivalent overloads:
组合流没有任何问题。这些对象是轻量级的,因为它们只引用源数据,而不像数组内容那样复制数据。这种轻量级物体的成本可能只有在实际有效载荷也非常小的情况下才是相关的。这些场景可以用专门的、语义上等效的重载来处理:
public void something(String required, String ... additional) {
somethingImpl(Stream.concat(Stream.of(required), Stream.of(additional)));
}
public void something(String required) {
somethingImpl(Stream.of(required));
}
public void something(String required, String second) {
somethingImpl(Stream.of(required, second));
}
private void somethingImpl(Stream<String> allParams) {
//... do what you want to do
}
so in the case of only one argument you're not only saving Stream
instances but also the varargs array (similar to Stream.of
's overload). This is a common pattern, see for example the EnumSet.of
overloads.
因此,在只有一个参数的情况下,您不仅要保存Stream
实例,还要保存varargs 数组(类似于Stream.of
的重载)。这是一种常见的模式,例如参见EnumSet.of
重载。
However, in a lot of cases even these simple overloads are not necessary and might be considered premature optimization (libraries like the JRE offer them as it's otherwise impossible for an application developer to add them if ever needed). If something
is part of an application rather than a library you shouldn't add them unless a profiler tells you that there's a bottleneck caused by that parameter processing.
然而,在很多情况下,即使这些简单的重载也不是必需的,并且可能被认为是过早优化(像 JRE 这样的库提供了它们,否则应用程序开发人员在需要时不可能添加它们)。如果something
是应用程序而不是库的一部分,则不应添加它们,除非分析器告诉您该参数处理导致瓶颈。
回答by Tagir Valeev
Third-party extensions to Stream API like my StreamExor jOOλprovide methods like append
or prepend
which allow you to do this in more clean way:
Stream API 的第三方扩展(如我的StreamEx或jOOλ)提供了类似append
或prepend
允许您以更简洁的方式执行此操作的方法:
// Using StreamEx
Stream<String> allParams = StreamEx.of(required).append(additional);
// Using jOOL
Stream<String> allParams = Seq.of(required).append(additional);
回答by andrepnh
If you're willing to use Guava, you may Lists.asList(required, additional).stream()
. The method was created to ease that varargs with minimum requirement idiom.
如果你愿意使用番石榴,你可以Lists.asList(required, additional).stream()
。创建该方法是为了以最低要求的习惯用法缓解可变参数。
A side note, I consider the library really useful, but of course it's not a good idea to add it just because of that. Check the docsand see if it could be of more use to you.
附带说明,我认为该库非常有用,但当然,仅仅因此而添加它并不是一个好主意。检查文档,看看它是否对您更有用。