4
votes

Pourquoi Stream.max accepte-t-il Integer.compare comme paramètre d'entrée?

La méthode stream.max utilise un comparateur mais Integer.compare n'implémente pas l'interface Comparator. La seule similitude est qu'ils partagent la même signature de méthode que la méthode compare (). Je suis donc assez confus sur les conditions préalables pour devenir un paramètre d'entrée de Comparator? Merci.

Exemple:

List<Integer> ls = Arrays.asList(9,2,5,8); 
System.out.println(ls.stream().max(Integer::compare).get());


0 commentaires

3 Réponses :


2
votes

Parce que dans ce contexte, Integer :: compare est équivalent à sa forme lambda:

new Comparator<Integer>() {
    @Override
    public int compare(Integer a, Integer b) {
        return Integer.compare(a, b);
    }
}

Et cette forme lambda est aussi logiquement équivalente à sa forme de classe anonyme :

(a, b) -> Integer.compare(a, b)


0 commentaires

2
votes

Le comparateur interface est une interface fonctionnelle, donc toute expression lambda ou référence de méthode dont la signature de méthode est conforme à l'interface fonctionnelle peut être utilisée.

La méthode compare prend deux objets, les compare et renvoie un int à des fins de commande. La référence de méthode Integer :: compare fait référence à Integer méthode compare , et la signature de cette méthode correspond, donc le compilateur autorise cette référence de méthode à résoudre à une instance de Comparator .

Les expressions Lambda et les références de méthode sont autorisées lors de la transmission en tant qu'argument à une méthode, de l'affectation à une variable et en tant qu'argument à un opérateur de conversion. Ici, votre référence de méthode est passée à une méthode en tant qu'argument, donc le compilateur voit cela comme du code légal.


0 commentaires

1
votes

Integer.compare (int, int) a une signature que nous pouvons utiliser pour implémenter Comparator .compare (Integer, Integer) . Comme Comparator est une interface fonctionnelle, nous pouvons utiliser une référence de méthode à Integer.compare pour fournir une implémentation de Comparator .

Ce formulaire utilise la méthode static Integer.compare (int, int) . Dans ce cas, lorsque le flux compare deux éléments, il effectue l'appel statique suivant:

element1.compareTo(element2);

Integer :: compare peut être utilisé pour fournir une implémentation de toute interface fonctionnelle qui a la même signature, telle que:

System.out.println(ls.stream().max(Integer::compareTo).get());

Une autre forme de référence de votre méthode consiste à utiliser:

BinaryOperator<Integer> bo = Integer::compare; //int functName(int, int)
BiFunction<Integer, Integer, Integer> bf = Integer::compare;

//or even
BiConsumer<Integer, Integer> bc = Integer::compare; //return value ignored


0 commentaires