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; });
wildcard?In generic code, the question mark (
?), called thewildcard, 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.
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 operationSo 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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With