2017-01-05 1 views
0

J'ai une List<Meeting> et assemblée est le suivant:Remplacé un comparateur personnalisé avec Comparator.comparing() - pourquoi cela fonctionne?

public class Meeting { 
    private Calendar date; 
    public Calendar getDate() { 
     return this.date 
    } 
} 

En avait à l'origine un comparateur personnalisé lambda dans la partie .sorted() d'un flux (myMeetingList est un List<Meeting>):

return myMeetingList.parallelStream() 
        .filter(m -> m.getContacts().contains(contact)) 
        .sorted((m1,m2) -> m1.getDate().compareTo(m2.getDate())) 
        .collect(Collectors.toList()); 

je suis tombé sur quelque chose complètement par accident. Je pense que cela fonctionne, mais je ne sais pas pourquoi. Au lieu de créer la comparaison personnalisée, je l'ai remplacé par ce qui ressemble à une référence de méthode statique:

return myMeetingList.parallelStream() 
        .filter(m -> m.getContacts().contains(contact)) 
        .sorted(Comparator.comparing(Meeting::getDate)) 
        .collect(Collectors.toList()); 

Je crois que cela fonctionne, mais honnêtement, je ne sais pas pourquoi. Le JavaDoc pour l'une des implémentations de Comparator.comparing() montre

static <T,U extends Comparable<? super U>> Comparator<T> comparing(Function<? super T,? extends U> keyExtractor) 

mais ont recherché quelques blogs et lisez la doc quelques fois, et je vais avoir du mal à déchiffrer que. La lecture de mon code actuel est logique, mais je n'aurais pas pu le faire moi-même sans vérifier l'exemple de JavaDoc. Quelqu'un at-il des idées sur la façon de mieux expliquer cela?

Répondre

2

Le code dans Comparator.comparing est juste:

Objects.requireNonNull(keyExtractor); 

return (Comparator<T> & Serializable) 
     (c1, c2) -> keyExtractor.apply(c1).compareTo(keyExtractor.apply(c2)); 

La première ligne est un chèque que le paramètre est non nulle.

La deuxième ligne renvoie un Comparator qui appelle simplement la fonction keyExtractor pour obtenir les valeurs à comparer et utilise leur méthode compareTo pour effectuer la comparaison. Les génériques dans la déclaration de comparing garantit que keyExtractor doit mettre en œuvre Comparable.

Dans votre cas, la référence de la méthode Meeting::getDate produira une fonction keyExtractor qui appelle simplement la méthode getDate, donc

keyExtractor.apply(c1) 

exécutera

c1.getDate() 

Ainsi, le résultat final est essentiellement le même que votre code original.

+0

Merci, donc le comparateur dans ce cas est un comparateur ? – NateH06

+0

Oui 'T' sera déduit comme' Calendar' –