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());
3 Réponses :
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)
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.
Integer.compare (int, int)
a une signature que nous pouvons utiliser pour implémenter Comparator
. 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