Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Generics - ? use

Tags:

java

generics

JDK documentation of java.util.Stream interface has the following code snippet as an example of Collector construction.

Collector<Widget, ?, TreeSet<Widget>> intoSet =
         Collector.of(TreeSet::new, TreeSet::add,
                      (left, right) -> { left.addAll(right); return left; });

The Collector.of method has the return type as static <T,R> Collector<T,R,R>

Does the ? in the return type in the example is just a convenient way to refer to the next generic type as those two have been declared as same in the method signature. And do all the following three statement are one and the same:

Collector<Widget, ?, TreeSet<Widget>> intoSet =
             Collector.of(TreeSet::new, TreeSet::add,
                          (left, right) -> { left.addAll(right); return left; });
Collector<Widget, TreeSet<Widget>, TreeSet<Widget>> intoSet =
             Collector.of(TreeSet::new, TreeSet::add,
                          (left, right) -> { left.addAll(right); return left; });
Collector<Widget, TreeSet<Widget>, ?> intoSet =
             Collector.of(TreeSet::new, TreeSet::add,
                          (left, right) -> { left.addAll(right); return left; });
like image 267
pawinder gupta Avatar asked Jan 01 '26 18:01

pawinder gupta


1 Answers

What is a wildcard?

In generic code, the question mark (?), called the wildcard, represents an unknown type. The wildcard can be used in a variety of situations: as the type of a parameter, field, or local variable; sometimes as a return type (though it is better programming practice to be more specific). The wildcard is never used as a type argument for a generic method invocation, a generic class instance creation, or a supertype.

Why is it used with Collector.of?

As you have already noticed Collector.of(Supplier<R> supplier, BiConsumer<R, T> accumulator, BinaryOperator<R> combiner, Characteristics... characteristics) returns an object of type Collector<T, R, R> knowing that the class Collector has 3 type parameters which are T, A and R where:

  • <T>: The type of input elements to the reduction operation.
  • <A>: The mutable accumulation type of the reduction operation (often hidden as an implementation detail)
  • <R>: The result type of the reduction operation

So as described in the javadoc we generally use a wildcard for the type parameter <A> because it is considered as an implementation detail since it is only an intermediate type, what really matter are the input and output type parameters respectively T and R so for the sake of simplicity/readability ? is preferred to what should theoretically be used which is TreeSet<Widget> in this case.

like image 84
Nicolas Filotto Avatar answered Jan 03 '26 11:01

Nicolas Filotto



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!