2

I have a list of management songs, so this is my criteria to sort now the songs. How can i "convert" this to a lambda expression?

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

3 Answers 3

3

Even simpler:

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

The parameter types are implied by the generic type of the Comparator.

Edit: it can be done even simpler that the above. The comparator does not need to be separately defined. The lambda expression can be passed immediately to the sort method. Also in that case the types of the parameters is implied by the generic type of your collection object. Hence:

gestionCancionList.sort((t1,t2) -> t1.vecesQueSeRepite == t2.vecesQueSeRepite ? 
            t1.song.dameInterprete().compareTo(t2.song.dameInterprete())
            : (int)(t2.vecesQueSeRepite - t1.vecesQueSeRepite));
Sign up to request clarification or add additional context in comments.

Comments

3

Use Comparator factory method with method references (where possible):

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

Making your code then:

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

The trick is to apply the reversed() to keep the code neat.

Note that explicit typing of the lambda is required when accessing a field (you haven't shown us what type vecesQueSeRepite is; I assumed Veces - substitute the actual type as needed).

5 Comments

Promising, but unfortunately vecesQueSeRespite is a field, not a method, and the comparison of those values is reversed.
@StuartMarks I've updated the code to use a reversed comparison of the vecesQueSeRespite field
Better, but it still doesn't work. :-) +1 for effort though. Type inference tends to break down when reversed() is used. Also, dameInterprete isn't a method on GestionCancion so you have to use a lambda instead of a method reference. To avoid the type inference problem, I had to write the lambdas with an explicit type for the lambda arg, e.g. (GestionCancion gc) -> gc.song.dameInterprete(). Finally, vecesQueSeRepite looks like a primitive of some type, so comparingInt or similar should be used to avoid boxing. Still, the result is preferable to the original or other answers.
(I'm not the OP, otherwise I'd accept your answer.) Regarding why reversed() worked for you and not for me: since you're using method references, they supply sufficient type information so that things work. If you adhere strictly to the OP's example, which uses fields, you have to use lambda expressions instead of method references. (Alas, there are no field references, yet.) The lambda expressions won't work unless you provide more explicit type information.
@StuartMarks quite so. Answer updated with the required explicit typing as per your comment. I'll remember that tip!
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);

An example here

2 Comments

Thank you very much, so i see the idea is if i am not using a single method, to wirite the same which is in compare method. I wonder why does not serve writing : "Comparator<GestionCancion> aName = (GestionCancion t1, GestionCancion t2)-> compare(t1,t2) "
I have also attached a simple example for reference.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.