Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why overload the varargs method of() in Java Stream interface?

The Stream interface has two overloads for the method of(). One of these is a variable-arity method while the other takes a single argument.

Is the single-argument method a performance optimization versus passing one argument to the variable-arity method? If so, how does it improve performance? The same questions could be asked of the empty() method, which would seem to be syntax sugar around the variable-arity of().

I see that the implementation differs between these methods, with the difference apparently being how the Spliterator is instantiated; but what advantage does this offer to the Stream API?

like image 684
jaco0646 Avatar asked Mar 04 '16 17:03

jaco0646


People also ask

Why do we use varargs in Java?

Variable Arguments (Varargs) in Java is a method that takes a variable number of arguments. Variable Arguments in Java simplifies the creation of methods that need to take a variable number of arguments.

What is the rule for using Varargs?

Rules for varargs:There can be only one variable argument in the method. Variable argument (varargs) must be the last argument.

Is it good to use varargs in Java?

Varargs are useful for any method that needs to deal with an indeterminate number of objects. One good example is String. format . The format string can accept any number of parameters, so you need a mechanism to pass in any number of objects.

What is Varargs method in Java?

Varargs is a short name for variable arguments. In Java, an argument of a method can accept arbitrary number of values. This argument that can accept variable number of values is called varargs. The syntax for implementing varargs is as follows: accessModifier methodName(datatype… arg) { // method body }

How do the overloading methods can be ambiguous?

Sometimes unexpected errors can result when overloading a method that takes a variable length argument. These errors involve ambiguity because both the methods are valid candidates for invocation. The compiler cannot decide onto which method to bind the method call.


2 Answers

Empty stream and single element stream are very common use-cases, especially when you utilize the .flatMap(). For example, here's how Optional.stream() is implemented in Java-9:

public Stream<T> stream() {
    if (!isPresent()) {
        return Stream.empty();
    } else {
        return Stream.of(value);
    }
}

So given the stream of Optionals you can unwrap them into the flat stream this way:

streamOfOptionals.flatMap(Optional::stream);

Here you create tons of empty streams as well as single element streams, so optimizing such cases looks very reasonable. In particular, Stream.empty() unlike Stream.of() does not create an empty array and does not create the spliterator (it reuses the same spliterator instance). Stream.of(T) is also particularly optimized inside the StreamBuilderImpl, so no array is allocated for single element.

like image 167
Tagir Valeev Avatar answered Sep 28 '22 08:09

Tagir Valeev


Yes, it's an optimization to avoid the overhead of creating an array to hold only a single element, which is what you'd get if you used the varargs version.

The same questions could be asked of the empty() method, which would seem to be syntax sugar around the variable-arity of()

What implementation version are you looking at? When I look at the implementation I don't see this.

like image 29
Louis Wasserman Avatar answered Sep 28 '22 08:09

Louis Wasserman