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>();
}
};