Avatar ·

¿Qué significa el operador "::" (doble dos puntos) en Java 8?

¡Hola a todos! Estoy aprendiendo Java 8 y me encontré con una sintaxis extraña con doble dos puntos "::". Lo he visto en ejemplos con expresiones lambda, pero no entiendo qué hace exactamente ni cuándo usarlo. Por ejemplo, sé cómo escribir una lambda para filtrar una lista de strings por longitud:
List<String> list = Arrays.asList("a", "bb", "ccc");
list.stream().filter(s -> s.length() > 1).forEach(s -> System.out.println(s));
Pero luego vi este código:
list.stream().filter(s -> s.length() > 1).forEach(System.out::println);
Aquí en lugar de `s -> System.out.println(s)` está escrito `System.out::println`. ¿Qué es esta magia? ¿Es lo mismo? ¿Por qué no simplemente usar una lambda? ¿Y cómo saber cuándo se puede escribir `::` y cuándo no? ¿Pueden explicarlo en palabras simples con ejemplos? También vi estas variantes:
list.stream().map(String::toUpperCase)
list.stream().sorted(String::compareToIgnoreCase)
¿Cómo es