Ajuda para entender ::

Olá!
Srs, preciso de ajuda pra entender como funciona os quatro pontos (::) em uma expressão lambda Java:
Ex:
List<String> list = saida.collect(Collectors.toCollection(ArrayList::new));

Li bastante sobre o tema mas simplesmente não consigo entender.

Alguém domina a ponto de literalmente desenhar um exemplo para me ajudar a entender?
Se puderem dar uma força ficarei grato.

ArrayList::new é uma referência ao construtor da classe ArrayList, essa sintaxe é chamada de Method Reference.

Existem quatro tipos de Method Reference:

  • Referência à um método estático de uma classe:
    NomeDaClasse::nomeDoMetodoEstatico

  • Referência à um método de instância de uma classe:
    NomeDaClasse::nomeDoMetodoNaoEstatico

  • Referência à um método de instância de um objeto:
    identificadorDoObjeto::nomeDoMetodo

  • Referência ao construtor de uma classe:
    NomeDaClasse::new

Basicamente você pode usar Method References em todo lugar onde se espera receber como parâmetro a implementação de uma interface funcional.
Ou seja, podes usar nos locais onde passaria uma classe anônima ou uma expressão lâmbda.

No caso do método Collectors.toCollection, ele espera receber um Supplier<TipoDaClasse> como parâmetro.

Então você poderia escrever se código de 3 formas diferentes:

Usando classe anônima:

List<String> list = saida.collect(Collectors.toCollection(new Supplier<ArrayList<String>>() {
	@Override
	public ArrayList<String> get() {
		return new ArrayList<String>();
	}
}));

Usando expressão lâmbda:

List<String> list = saida.collect(Collectors.toCollection(() -> new ArrayList<String>()));

E finalmente, usando Method Reference:

List<String> list = saida.collect(Collectors.toCollection(ArrayList::new));

Vale lembrar que, assim como classes, anônimas e expressões lâmbda, o uso de Method Reference não se limita somente à passagem de parâmetros, pois você pode muito bem utilizar uma Method Reference para inicializar um objeto de uma interface funcional, veja só:

Method Reference:

Supplier<ArrayList<String>> supplier = ArrayList::new;

Expressão lâmbda:

Supplier<ArrayList<String>> supplier = () -> new ArrayList<String>();

Classe anônima:

Supplier<ArrayList<String>> supplier = new Supplier<ArrayList<String>>() {
    @Override
    public ArrayList<String> get() {
        return new ArrayList<String>();
    }
};
2 curtidas

staroski, muito obrigado pelo empenho em ajudar! Vou estudar mains sobre Method Reference pois ainda me parece complexo mas com seu texto ja tenho um norte pra estudos. vlw mesmo.:+1: