Java 8 threads and varargs

According to Effective Java 2nd Ed, when you want to write a method signature that allows the use of varargs, but still keeps that you have one minimum of the element at compile time, you must write the method signature as follows:

public void something(String required, String ... additional) { //... do what you want to do } 

If I want to convey all of these elements, I did 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 seems very elusive and wasteful, especially because I create thread 1 and combine it with another. Is there a cleaner way to do this?

+7
java java-8 java-stream variadic-functions
source share
5 answers

Here's how to do it without creating two Streams , although you may not like it.

 Stream.Builder<String> builder = Stream.<String>builder().add(required); for (String s : additional) { builder.add(s); } Stream<String> allParams = builder.build(); 
+6
source share

Unfortunately, Java can be quite verbose. But another option to facilitate this is to simply use static imports. In my opinion, this does not make your code less clear, since each method is associated with a thread.

 Stream<String> allParams = concat(of(required), of(additional)); 
+2
source share

There is nothing wrong with composite threads. These objects are lightweight because they relate only to the source data, but do not copy data, such as the contents of the array. The cost of such a lightweight facility can only be relevant if the actual payload is also very small. Such scenarios can be processed 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 } 

therefore, in the case of only one argument, you not only save instances of Stream , but also a varargs array (similar to overloading Stream.of s). This is a common template; see, for example, the overloads of EnumSet.of .

However, in many cases, even these simple overloads are not needed and can be considered premature optimization (libraries like JRE offer them, because otherwise the application developer can add them if it is ever needed). If something is part of the application, not the library, you should not add them unless the profiler tells you that this is a bottleneck caused by this parameter processing.

+2
source share

If you want to use Guava, you can Lists.asList(required, additional).stream() . This method was created to facilitate this varargs with a minimum requirement.

Note, I believe that the library is really useful, but, of course, it is not recommended to add it just because of this. Check out the docs and see if it can be more useful to you.

+1
source share

Third-party extensions for the Stream API, such as StreamEx or jOOλ, provide methods such as append or prepend that allow you to do this in a cleaner way:

 // Using StreamEx Stream<String> allParams = StreamEx.of(required).append(additional); // Using jOOL Stream<String> allParams = Seq.of(required).append(additional); 
+1
source share

All Articles