Algo peculiar que tropezó el otro día.
Considere el siguiente código (que recoge los distintos recuentos de longitud de palabra de los dados String
s, pero eso no es importante):
static void collectByLambda(Collection<String> list) {
Collection<Integer> collected = list.stream().collect(Collectors.collectingAndThen(
Collectors.groupingBy(String::length),
m -> m.keySet()
));
}
y su versión de referencia método equivalente:
static void collectByMethodReference(Collection<String> list) {
Collection<Integer> collected = list.stream().collect(Collectors.collectingAndThen(
Collectors.groupingBy(String::length),
Map::keySet
));
}
El primero (lambda) versión no requiere que import java.util.Map
permite compilar, el segundo lo hace.
¿Por qué es esto exactamente? Me puedo imaginar que es porque la segunda versión tiene que tener acceso a la Map
clase en tiempo de compilación para construir la referencia; pero ¿cómo sabe que Map#keySet()
existe incluso si no importa Map
?
Tenga en cuenta que import
es sólo un medio para permitir que el uso de nombres de clase no cualificado en su código, nada más.
Desde el primer ejemplo no menciona explícitamente el nombre de la clase Map
que no hay necesidad de permitir la notación abreviada, mientras que el segundo ejemplo lo menciona. Tenga en cuenta que el segundo ejemplo funcionará sin importar cuando se utiliza el nombre completo:
static void collectByMethodReference(Collection<String> list) {
Collection<Integer> collected = list.stream().collect(Collectors.collectingAndThen(
Collectors.groupingBy(String::length),
java.util.Map::keySet
));
}