web-dev-qa-db-fra.com

Nouvelle instanciation d’objet lors de l’utilisation de Java 8 flux

Y a-t-il une différence dans l'utilisation des constructions suivantes, autre qu'une lisibilité légèrement meilleure dans ces dernières?

someList.stream().map(item -> new NewClass(item)).collect(Collectors.toList());

someList.stream().map(NewClass::new).collect(Collectors.toList());
37
ShellDragon

Généralement il n'y a pas de différence. NewClass::new produit moins de bytecode car dans la version lambda, une méthode privée générée automatiquement est créée par le compilateur Java du corps lambda), tandis que NewClass:new relie directement au handle de méthode du constructeur. Donc, en utilisant des références de méthodes, vous aurez peut-être légèrement moins de taille de fichier de classe. Aucune différence de performance significative n'est toutefois attendue.

Une autre différence est la procédure de résolution de la méthode. Ce n'est pas applicable dans votre exemple particulier, mais peut être applicable dans un autre code. Par exemple, vous avez deux constructeurs:

public NewClass(String a) {...}
public NewClass(String a, String b) {...}

Et vous avez une méthode qui accepte une interface fonctionnelle:

public myMethod(Function<String, NewClass> fn) {...}

Ensuite, vous pouvez appeler les deux avec lambda ou une interface fonctionnelle:

myMethod(str -> new NewClass(str));
myMethod(NewClass::new);

Mais supposons que plus tard, vous ajoutiez une nouvelle méthode portant le même nom, comme ceci:

public myMethod(BiFunction<String, String, NewClass> fn) {...}

Alors, l'appel à la référence de méthode deviendra ambigu et entraînera une erreur de compilation sous la forme NewClass::new correspond maintenant aux deux constructeurs, tandis que lambda est toujours non ambigu.

42
Tagir Valeev