Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does calling a method not require an import of the class? [duplicate]

Something peculiar I stumbled upon the other day.

Consider the following code (it collects the distinct word length counts of the given Strings, 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?

like image 802
daniu Avatar asked Aug 28 '18 11:08

daniu


Video Answer


1 Answers

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
    ));
}
like image 121
piet.t Avatar answered Oct 10 '22 22:10

piet.t