Something peculiar I stumbled upon the other day.
Consider the following code (it collects the distinct word length counts of the given String
s, but that's not important):
static void collectByLambda(Collection<String> list) {
Collection<Integer> collected = list.stream().collect(Collectors.collectingAndThen(
Collectors.groupingBy(String::length),
m -> m.keySet()
));
}
and its equivalent method reference version:
static void collectByMethodReference(Collection<String> list) {
Collection<Integer> collected = list.stream().collect(Collectors.collectingAndThen(
Collectors.groupingBy(String::length),
Map::keySet
));
}
The first (lambda) version does not require you to import java.util.Map
to compile, the second one does.
Why is this exactly? I can imagine it's because the second version needs to have access to the Map
class at compile time to build the reference; but how does it know that Map#keySet()
even exists if it doesn't import Map
?
Note that import
is only a means to allow you using unqualified class-names in your code, nothing more.
Since the first example never explicitly mentions the class name Map
there is no need to allow for the abbreviated notation, while the second example does mention it. Note that the second example will work without the import when using the fully qualified name:
static void collectByMethodReference(Collection<String> list) {
Collection<Integer> collected = list.stream().collect(Collectors.collectingAndThen(
Collectors.groupingBy(String::length),
java.util.Map::keySet
));
}
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