Java方法签名:Stream与Collection对比var-arg

时间:2021-02-21 19:09:58

Is there a general best approach for var-arg method signatures with respect to the Java 8 Lambda/Closure?

对于Java 8 Lambda / Closure,是否有针对var-arg方法签名的一般最佳方法?

In a situation where a method is used either with a single object as a parameter or a collection of objects I see three options to realize this:

在使用单个对象作为参数或对象集合的方法的情况下,我看到三个选项来实现这一点:

 private void optionOneVararg(String... params) { ... }
 private void optionTwoCollection(Collection<String> params) { ... }
 private void optionThreeStream(Stream<String> params) { ... }

The String class is obviously used as an example.

String类显然用作示例。

Is there a general valid "best practise" approach to this? The vararg approach produced the slickest code up to Java 7. With streams it feels clumsy.

对此有一般的有效“最佳实践”方法吗? vararg方法产生了最简洁的代码,直到Java 7.对于流,它感觉很笨拙。

I would like to be able to use the convenience of lambdas both inside the method and outside where I call it. Also I would like to keep wrapping/gluecode (e.g. Collections.singletonList(element) or Arrays.asList(element)) to a minimum and avoid using Collection myCollection = stream.collect(...) followed by a myCollection.stream().

我希望能够在方法内部和外部调用它时使用lambda的便利性。另外我想保持包装/ gluecode(例如Collections.singletonList(element)或Arrays.asList(element))到最小化并避免使用Collection myCollection = stream.collect(...)后跟myCollection.stream() 。

2 个解决方案

#1


2  

You can still use the Stream API and lambdas in the method by invoking Stream.of(String...). In this case you can keep the signature with the varargs:

您仍然可以通过调用Stream.of(String ...)在方法中使用Stream API和lambdas。在这种情况下,您可以使用varargs保留签名:

private void optionVarArgs(String... params) {
   Stream.of(params)...
   ...
}

#2


0  

Thanks to AR.3s answer I realized that keeping the Stream as a parameter is superior in both the performance and the esthetic aspect:

感谢AR.3s的回答,我意识到保持Stream作为参数在性能和美学方面都是优越的:

private void callOptionThreeFromStream() {
    List<String> foo = Arrays.asList(new String[] { "a", "b", "c" });
    Stream<String> stream = foo.stream();
    // use stream here
    optionThreeStream(stream);
}
private void callOptionThreeFromObject() {
    String bar = "a";
    optionThreeStream(Stream.of(bar)); //very simple conversion
}
private void optionThreeStream(Stream<String> params) {
    // use the same stream (and possibly profit from optimization)
}

Using a vararg parameter causes more overhead (at least esthetically):

使用vararg参数会导致更多开销(至少是美学上的):

private void callOptionOneFromStream() {
    List<String> foo = Arrays.asList(new String[] { "a", "b", "c" });
    Stream<String> stream = foo.stream();
    // use stream here
    optionOneVararg(stream.toArray(String[]::new)); //still clumsy
}
private void callOptionOneFromObject() {
    String bar = "a";
    optionOneVararg(bar); //but optimal here
}
private void optionOneVararg(String... params) {
    Stream<String> stream = Stream.of(params);
    // use the new stream on the newly created array
}

And for the sake of completeness:

为了完整起见:

private void callOptionTwoFromStream() {
    List<String> foo = Arrays.asList(new String[] { "a", "b", "c" });
    Stream<String> stream = foo.stream();
    // use stream here
    optionTwoCollection(stream.collect(Collectors.toList())); //clumsy
}
private void callOptionTwoFromObject() {
    String bar = "a";
    optionTwoCollection(Collections.singletonList(bar)); //clumsy
}
private void optionTwoCollection(Collection<String> params) {
    Stream<String> stream = params.stream();
    // use the new stream on the newly created collection
}

My personal conclusion: Use Stream for private methods. Keeping var-arg or Collections in public API methods might be better suited though to hide internal technical details.

我的个人结论:使用Stream进行私有方法。在公共API方法中保留var-arg或Collections可能更适合隐藏内部技术细节。

It's a nice detail that Stream.of uses a var-arg parameter to cover arrays and single objects at once.

这是一个很好的细节,Stream.of使用var-arg参数一次覆盖数组和单个对象。

#1


2  

You can still use the Stream API and lambdas in the method by invoking Stream.of(String...). In this case you can keep the signature with the varargs:

您仍然可以通过调用Stream.of(String ...)在方法中使用Stream API和lambdas。在这种情况下,您可以使用varargs保留签名:

private void optionVarArgs(String... params) {
   Stream.of(params)...
   ...
}

#2


0  

Thanks to AR.3s answer I realized that keeping the Stream as a parameter is superior in both the performance and the esthetic aspect:

感谢AR.3s的回答,我意识到保持Stream作为参数在性能和美学方面都是优越的:

private void callOptionThreeFromStream() {
    List<String> foo = Arrays.asList(new String[] { "a", "b", "c" });
    Stream<String> stream = foo.stream();
    // use stream here
    optionThreeStream(stream);
}
private void callOptionThreeFromObject() {
    String bar = "a";
    optionThreeStream(Stream.of(bar)); //very simple conversion
}
private void optionThreeStream(Stream<String> params) {
    // use the same stream (and possibly profit from optimization)
}

Using a vararg parameter causes more overhead (at least esthetically):

使用vararg参数会导致更多开销(至少是美学上的):

private void callOptionOneFromStream() {
    List<String> foo = Arrays.asList(new String[] { "a", "b", "c" });
    Stream<String> stream = foo.stream();
    // use stream here
    optionOneVararg(stream.toArray(String[]::new)); //still clumsy
}
private void callOptionOneFromObject() {
    String bar = "a";
    optionOneVararg(bar); //but optimal here
}
private void optionOneVararg(String... params) {
    Stream<String> stream = Stream.of(params);
    // use the new stream on the newly created array
}

And for the sake of completeness:

为了完整起见:

private void callOptionTwoFromStream() {
    List<String> foo = Arrays.asList(new String[] { "a", "b", "c" });
    Stream<String> stream = foo.stream();
    // use stream here
    optionTwoCollection(stream.collect(Collectors.toList())); //clumsy
}
private void callOptionTwoFromObject() {
    String bar = "a";
    optionTwoCollection(Collections.singletonList(bar)); //clumsy
}
private void optionTwoCollection(Collection<String> params) {
    Stream<String> stream = params.stream();
    // use the new stream on the newly created collection
}

My personal conclusion: Use Stream for private methods. Keeping var-arg or Collections in public API methods might be better suited though to hide internal technical details.

我的个人结论:使用Stream进行私有方法。在公共API方法中保留var-arg或Collections可能更适合隐藏内部技术细节。

It's a nice detail that Stream.of uses a var-arg parameter to cover arrays and single objects at once.

这是一个很好的细节,Stream.of使用var-arg参数一次覆盖数组和单个对象。