It allows to use function or lambda where second argument type doesn't need to be exact type T
of stream, but may be any of its supertype. This allows to:
For example, thus you can use for Stream<Integer>
accumulator that accepts Number
, or for Stream<String>
accumulator accepting CharSequence
or even Object
.
More important, this follows common JDK API style: in every signature, where narrower or wider type can be used, it should be used. I never see this rule documented, but I don't know any exception to this rule in JDK.
See What is PECS SO question for a better explanation.
For example, accumulator to count distinct items of any stream, may look like:
public class DistinctCounter {
Set<Object> set = new HashSet<>();
// count() accepts object of any type
public int count(int prev, Object item) {
return prev + set.add(item) ? 1 : 0;
}
}
and may be used for Stream<String>
as follows:
Stream<String> stream = ...
final DistinctCounter c = new DistinctCounter();
int count = stream.reduce(0, c::count, Integer::add);
Though this example is not very practical, hope it will help to understand.