编程有一条原则如下:
避免创建不必要的对象:最好能重用对象,而不要在每次需要的时候就创建一个相同功能的新对象。
请看如下代码:
List<String> names = Arrays.asList("peter", "anna", "mike", "xenia");
// 1、匿名内部类
Collections.sort(names, new Comparator<String>() {
@Override
public int compare(String a, String b) {
return b.compareTo(a);
}
});
//2、lambda表达式
Collections.sort(names, (a, b) -> b.compareTo(a));
是不是每次排序都创建了一个新的Comparator对象,导致性能降低?那么还主张使用Lambda表达式吗?
Répondez d'abord à votre question :
Un nouvel objet Comparator est-il créé à chaque tri, ce qui entraîne une réduction des performances ? Alors, préconisez-vous toujours d’utiliser des expressions Lambda ?
Non, je préconise
La raison fondamentale
Lamdba signifie qu'il ne s'agit pas du tout de sucre syntaxique pour les classes internes anonymes. C'est-à-dire que l'implémentation sous-jacente de l'expression Lambda n'est pas du tout l'implémentation de classes internes anonymes. Ce sont en fait deux choses
Comment le prouver ?
Les classes internes anonymes généreront en fait un fichier de classe lors de la compilation, nommé avec des numéros ClassName$, donc si la couche inférieure de l'expression Lamdba est également implémentée par des classes internes anonymes, elle générera certainement des fichiers internes similaires
Nous écrivons donc simplement votre exemple dans des classes sous différents packages, puis vérifions l'effet compilé
Une classe interne anonyme implémente InnerTest
Ceci est un fichier de classe, vous pouvez voir qu'il y en a deux
expression lambda LamdbaTest
Cependant, il n'y a qu'un seul fichier de classe
Donc il n'y a qu'une seule vérité, haha, évidemment, ce n'est pas du tout la même chose
Comment l'expression Lamdba est-elle implémentée ?
Nous pouvons jeter un œil à leur bytecode, afin que les différences sous-jacentes soient pleinement démontrées
InnerTest
LamdbaTest
Vous pouvez voir que les instructions utilisées par les deux sont différentes. Lors de l'analyse des expressions Lamdba, la nouvelle instruction Invocationdynamic de Java 7 est utilisée. Si vous connaissez cette instruction, vous pouvez la comprendre instantanément. familier, vous pouvez demander à Du Niang
Mais vous pouvez le comprendre directement à partir du nom de cette commande : Appel dynamique
Par conséquent, contrairement aux classes internes anonymes qui sont compilées dans un fichier de classe, Lamdba L'expression est compilée dans une méthode statique. Nous pouvons le revoir en regardant -p La méthode générée est nommée
lambda$main
.
.Encore une chose
En fait, vous pouvez voir que les expressions lamba sont en effet bien meilleures que les classes internes anonymes dans un sens, qu'il s'agisse de performances, de lisibilité ou de tendance générale ~ Haha, je veux pour dire tendance générale, car l'expression lamdba peut être optimisée dans un espace plus large. Quoi qu'il en soit, j'ai l'habitude de l'utiliser en java, et j'aime bien
Chaque tri ne crée pas de nouvel objet
Comparator
Généralement, une fois l'instance correspondant à l'expression Lambda générée en mémoire, la JVM sera réutilisée ci-dessous. Pour des instructions spécifiques, veuillez vous référer à ce lien : Évaluation d'exécution des expressions LambdaEn partant du principe que cela peut améliorer la lisibilité du programme et l'efficacité du développement, il est recommandé d'utiliser l'Lambdaexpression
Vous pouvez déclarer statiquement un objet de classe anonyme dans une expression Lambda
Les petits objets qui vont et viennent ne sont pas un gros problème pour la JVM