2016-11-22 1 views
1

J'ai une liste de chansons de gestion, donc c'est mon critère pour trier maintenant les chansons. Comment puis-je "convertir" cela en une expression lambda?Comment puis-je convertir un comparateur spécifique en une expression Lambda?

gestionCancionList.sort(new Comparator<GestionCancion>() { 
     @Override 
     public int compare(GestionCancion t1, GestionCancion t2){ 
      return t1.vecesQueSeRepite == t2.vecesQueSeRepite ? 
        t1.song.dameInterprete().compareTo(t2.song.dameInterprete()) 
        : (int)(t2.vecesQueSeRepite - t1.vecesQueSeRepite); 
     } 
    } 

Répondre

1

Encore plus simple:

Comparator<GestionCancion> aName = (t1,t2) -> t1.vecesQueSeRepite == t2.vecesQueSeRepite ? 
      t1.song.dameInterprete().compareTo(t2.song.dameInterprete()) 
      : (int)(t2.vecesQueSeRepite - t1.vecesQueSeRepite); 

Les types de paramètres sont implicites par le type générique de la comparaison.

Modifier: cela peut être fait encore plus simplement que ci-dessus. Le comparateur n'a pas besoin d'être défini séparément. L'expression lambda peut être transmise immédiatement à la méthode de tri. Dans ce cas également, les types de paramètres sont impliqués par le type générique de votre objet de collection. Par conséquent:

gestionCancionList.sort((t1,t2) -> t1.vecesQueSeRepite == t2.vecesQueSeRepite ? 
      t1.song.dameInterprete().compareTo(t2.song.dameInterprete()) 
      : (int)(t2.vecesQueSeRepite - t1.vecesQueSeRepite)); 
0

Simple

Comparator<GestionCancion> aName = (GestionCancion t1, GestionCancion t2)->t1.vecesQueSeRepite == t2.vecesQueSeRepite ? 
       t1.song.dameInterprete().compareTo(t2.song.dameInterprete()) 
       : (int)(t2.vecesQueSeRepite - t1.vecesQueSeRepite); 

Un exemple here

+0

Merci beaucoup, donc je vois l'idée est si je n'utilise pas une seule méthode, d'utiliser le même qui est dans la méthode de comparaison. Je me demande pourquoi ne sert pas à écrire: "Comparateur aName = (GestionCancion t1, GestionCancion t2) -> comparer (t1, t2)" –

+0

J'ai également joint un exemple simple pour référence. – Raghuveer

3

Utilisez la méthode d'usine Comparator avec des références de méthode (si possible):

Comparator.<GestionCancion, Veces>comparing(gc -> gc.vecesQueSeRepite).reversed() 
    .thenComparing(GestionCancion::dameInterprete); 

Faire votre code puis:

gestionCancionList.sort(
    Comparator.<GestionCancion, Veces>comparing(gc -> gc.vecesQueSeRepite).reversed() 
    .thenComparing(GestionCancion::dameInterprete)); 

L'astuce consiste à appliquer la reversed() de garder la code soigné.

Notez que le typage explicite du lambda est requis lors de l'accès à un champ (vous ne nous avez pas indiqué le type vecesQueSeRepite, je suppose que Veces - remplacez le type réel par le besoin).

+0

Prometteur, mais malheureusement 'vecesQueSeRespite' est un champ, pas une méthode, et la comparaison de ces valeurs est inversée. –

+0

@StuartMarks J'ai mis à jour le code pour utiliser une comparaison inversée du champ 'vecesQueSeRespite' – Bohemian

+0

Mieux, mais cela ne fonctionne toujours pas. :-) +1 pour l'effort si. L'inférence de type tend à se décomposer lorsque '' reverse() '' est utilisé. De plus, 'dameInterprete' n'est pas une méthode sur' GestionCancion' donc vous devez utiliser un lambda au lieu d'une référence de méthode. Pour éviter le problème d'inférence de type, j'ai dû écrire les lambdas avec un type explicite pour l'argument lambda, par ex. '(GestionCancion gc) -> gc.song.dameInterprete()'. Enfin, 'vecesQueSeRepite' ressemble à une primitive d'un certain type, donc' comparisonInt' ou similaire devrait être utilisé pour éviter la boxe. Cependant, le résultat est préférable à l'original ou à d'autres réponses. –