lambda est une fonction anonyme, nous pouvons être compris comme un code pour lambda peut être passé (code d'accès est le même que les données), vous pouvez écrire plus concis et le code plus souple.
Regardez d' abord les implémentations de classe internes anonymes d' origine (par exemple dans un comparateur)
// classes internes anonymes mise en œuvre originale test1 public void () { // définir une classe interne anonyme Comparator Comparator <entier> = new new Comparator Comparator <Entier> () { @Override public int Comparer (O1 entier, Entier O2) { retour Integer.compare (O1, O2); } }; // classes internes anonymes comme un objet passé TreeSet <Entier> = new new TreeSet TreeSet <> (Comparator); }
Le code ci-dessus est en fait un code utile en fait que deux lignes (ligne 7), mais il a besoin d'écrire beaucoup de code si, très douloureux, bonne lambda solution au problème.
la mise en œuvre lambda
// expression lambda à mettre en œuvre test2 public void () { // expression lambda Comparator <Entier> = Comparator (X, Y) -> Integer.compare (X, Y); // classes internes anonymes comme un objet passé TreeSet <Entier> = new new TreeSet TreeSet <> (Comparator); }
De ce qui précède peut être vu, les lignes originales de code, la ligne devient réalisé, montant considérablement réduit grand nombre de code, mais seulement si une telle conclusion, ne peut évidemment pas convaincre les gens ( les classes internes anonymes je peux générer directement une clé, à développer il a dit que l'impact est pas grand, mais d'apprendre une nouvelle syntaxe, le rapport d'entrée-sortie est pas trop grand)
donc donner un autre exemple pour illustrer les avantages de lambda:
Exigence 1: Obtenir les employés dans plus de 35 ans de l'entreprise vieux
Tout d'abord créer des classes d'entités
emballer com.example.jdk8demo.lambda; importation lombok.AllArgsConstructor; importation lombok.Data; importation lombok.RequiredArgsConstructor; importation lombok.ToString; @Data @RequiredArgsConstructor @AllArgsConstructor @ToString publique classe employeur { privé nom de chaîne; privé âge entier; privé à double salaire; }
Pour faciliter la présentation, les opérations de base de données ne sont plus directement simulent un ensemble d'employés
/ * * * Set employés analogiques * / privé Liste <employeur> Liste = Arrays.asList ( nouveau nouvel employeur ( " Joe Smith " , 18 est , 2222,22 ), nouveau nouvel employeur ( " John Doe " , 32 , 3333,33 ), nouveau nouvel employeur ( " Wang Wu " 52 , 4444,44 ), nouveau nouvel employeur ( " Zhao six " , 44 , 5555,55 ), nouveau nouvel employeur ( " Tianqi " , 8 , 4235,32 ), nouveau nouvel employeur ( " bétail huit " , 28 , 3256,52 ) );
code logique est alors mis en œuvre, nous allons définir directement une méthode générale pour obtenir, le code suivant représenté sur la figure.
/ * * *查询年龄大于35岁的员工 * @return * / publique Liste <Employeur> getEmpolyerByAge () { Liste <employeur> employerList = nouveau ArrayList <> (); pour ( l' employeur de l' employeur: liste) { si (employer.getAge ()> 35 ) { employerList.add (employeur); } } Retourner employerList; }
Donc, si cette fois-ci, encore une fois une demande
Exigence 2: salaire Interrogation supérieur à 4000 employés
Nous avons également besoin d'écrire une méthode de mise en œuvre
/ * * *查询工资大于4000的员工 * @return * / publique Liste <Employeur> getEmpolyerBySalary () { Liste <employeur> employerList = nouveau ArrayList <> (); pour ( l' employeur de l' employeur: liste) { si (employer.getSalary ()> 4000 ) { employerList.add (employeur); } } Retourner employerList; }
Vous trouverez les deux méthodes, que employer.getAge ()> 35 et employer.getSalary ()> 4000 est différent du reste du code est le même, s'il y a une augmentation subséquente de nouveaux besoins similaires, il serait code redondant de plus en plus, nous avons donc besoin d'optimiser le code.
Optimisation option: Utiliser le modèle de stratégie
En général, pour ce code redondant, nous utiliserons la stratégie du mode optimisation pour optimiser
Tout d'abord, créer une interface
emballer com.example.jdk8demo.lambda; publique Interface EmpolyerService <T> { filtre booléen (T t); }
Ensuite, pour différents besoins, faire différentes classes de mise en œuvre
La première classe de mise en œuvre est supérieure à l'âge de 35 employés pour l'enquête
emballer com.example.jdk8demo.lambda; publique classe EmpolyerImplByage outils EmpolyerService <Employeur> { @Override publique filtre booléen (employeur de l' employeur) { retour employer.getAge ()> 35 ; } }
La seconde est la classe de mise en œuvre pour les entreprises à plus de 4000 employés
emballer com.example.jdk8demo.lambda; publique classe EmpolyerImplBySalary outils EmpolyerService <Employeur> { @Override publique filtre booléen (employeur de l' employeur) { retour employer.getSalary ()> 4000 ; } }
Ensuite, la politique est d'utiliser le mode de requête, la référence est de parvenir à une méthode de l'interface de classe et ensuite traitée différemment selon les différentes implémentations des méthodes d'interface de classe de mise en œuvre.
/ * * *使用策略模式查询员工信息 * @param empolyerService * @return * / publique Liste <Employeur> getEmpolyerList (EmpolyerService <Employeur> empolyerService) { Liste <employeur> employerList = nouveau ArrayList <> (); pour ( l' employeur de l' employeur: liste) { si (empolyerService.filter (employeur)) { employerList.add (employeur); } } Retourner employerList; }
Méthode mode stratégie demande finale sont tous appel unifié nouvelle référence spécifique est l'interface dans une catégorie spécifique
/ * * *优化一:采用策略模式 * / publics vides test5 () { Liste <Employeur> = employerList getEmpolyerList ( nouveau EmpolyerImplByage ()); pour ( l' employeur de l' employeur: employerList) { log.info (employer.toString ()); } Log.info ( " ============================================ = " ); employerList = getEmpolyerList ( nouveau EmpolyerImplBySalary ()); pour ( l' employeur de l' employeur: employerList) { log.info (employer.toString ()); } }
Cette optimisation il y a de mauvais endroits, est une exigence de créer une classe de mise en œuvre, ainsi que la demande accrue, la classe de mise en œuvre sera de plus en plus, il est temps d'affiner la recherche
Optimisation option: Utiliser une classe interne anonyme
En conséquence du modèle de stratégie, vous devez créer une demande pour une classe de mise en œuvre, ce qui conduit au dossier augmenté, de sorte que vous pouvez changer le mode de stratégie à utiliser la classe interne anonyme, en utilisant des classes internes anonymes, toujours besoin de filtrer l'interface ci-dessus, mais plus besoin d'utiliser l'interface classe d'implémentation
/ * * *优化方式二:匿名内部类 * / publics vides test6 () { Liste <Employeur> = employerList getEmpolyerList ( nouveau EmpolyerService <Employeur> () { @Override publique filtre booléen (employeur de l' employeur) { retour employer.getAge ( )> 20 ; } }); pour ( l' employeur de l' employeur: employerList) { log.info (employer.toString ()); } Log.info ( " ============================================ = " ); employerList= GetEmpolyerList ( nouveau EmpolyerService <Employeur> () { @Override publique filtre booléen (employeur de l' employeur) { retour employer.getSalary ()> 3000 ; } }); pour ( l' employeur de l' employeur: employerList) { log.info (employer.toString ()); } }
Ayant correspond donc au temps du début de cet article, un code de classe interne anonyme est réellement utile sur une ligne, mais le manque de besoin d'écrire un certain nombre d'autres codes inutilisés, de sorte que vous pouvez utiliser lambda optimisation.
Optimisation Troisième option: Utilisation lambda
/ * * *优化方式七: lambda表达式 * / publique vide test7 () { LambdaTest lambdaTest = nouveau LambdaTest (); Liste <Employeur> employerList = lambdaTest.getEmpolyerList ((e) -> e.getAge ()> 30 ); employerList.forEach (système. out :: println); log.info ( " ============================================= " ); employerList = lambdaTest.getEmpolyerList ((E) -> e.getSalary ()> 3000 ); employerList.forEach (système. out :: println); }
Vous trouverez, l'utilisation des expressions lambda, le code est simple et concis. Ici, pourquoi utiliser lambda a été décrite est terminée, mais pour java8, il y a de façon encore plus concise de l'optimisation est de flux Stream.
Optimisation de quatre façons: flux flux
Pour cette mise en œuvre, nous ne devons pas les mêmes que les trois premières nouvelles façons d'optimiser l'interface, où la filtration de flux peut être utilisé directement.
/ * * * Requête StreamAPI en utilisant les informations des employés * / publics vide test8 () { list.stream () // diffusion en continu .filter ((E) -> e.getSalary ()> 2000 ) // plus filtré salaire de 2000 le personnel .filter ((E) -> e.getAge ()> 30 ) // filtré les employés âgés de plus de 30 .limit ( 2 ) // seulement les deux premières requêtes .foreach (le système. oUT :: println); // impression de boucle }