Maximum de Flux, de la coutume de Comparaison
Ci-dessous mon code écrit spécifiquement pour une utilisation personnalisée Comparator
avec max
dans Java 8 Stream
.
import java.math.BigDecimal;
import java.util.*;
public class BigDecimalMax {
public static BigDecimal getBigDecimalMax(List<forTest> list) {
return list.stream()
.filter(t -> t.id % 2 == 0)
.max(forTestComparator::compare) //<-- syntax error ----------
.orElse(null);
}
public static class forTestComparator implements Comparator<forTest> {
@Override
public int compare(forTest val1, forTest val2) {
return val1.value.compareTo(val2.value);
}
}
public static void main(String[] args) {
List<forTest> lst = new ArrayList<>();
Random rn = new Random();
BigDecimalMax bdm = new BigDecimalMax();
for (int i=1; i<22; ++i) {
lst.add(bdm.new forTest(i, BigDecimal.valueOf(rn.nextLong())));
}
System.out.println(getBigDecimalMax(lst));
}
class forTest {
public int id;
public BigDecimal value;
forTest(int id, BigDecimal value) {
this.id = id;
this.value = value;
}
@Override
public String toString() {
return "forTest{" +
"id=" + id +
", value=" + value +
'}';
}
}
}
J'obtiens une erreur de syntaxe sur une méthode de référence à laquelle je ne comprends pas.
Error:(15, 18) java: incompatible types: invalid method reference
cannot find symbol
symbol: method compare(BigDecimalMax.forTest, BigDecimalMax.forTest)
location: class BigDecimalMax.forTestComparator
alors que IntelliJ IDEA se plaint que Non-static method cannot be referenced from a static context
.
Exactement ce que je fais mal?
EXPLICATION COMPLÉMENTAIRE (04/24/14):
-
Je comprends maintenant la raison de l'erreur de syntaxe. Merci.
-
A été personnalisé
Comparator
réellement nécessaire ici?
Depuis BigDecimal
implémente Comparable
mais ne pas semblent mettre en œuvre Comparator
( il a CompareTo()
mais pas Compare()
), j'ai pensé que la coutume Comparator
était nécessaire. C'est pourquoi je ne pouvais pas l'utiliser Comparator.comparing(ft -> ft.value)
. Est-il une faille dans ma logique?
ft -> ft.value
pour extraire un BigDecimal (ce qui est Comparable) à partir de la ForTest, et la passer lambda à celui-arg Comparateur.comparer() pour créer un Comparateur donné les instances Comparables.J'ai lu
comparing
description plusieurs fois, mais seulement après la lecture de votre réponse (plusieurs fois), j'ai réalisé ce que cela signifiait. Donc, comparaing
sert comme un pont entre Comparator
et Comparable
, droit?Oui c'est une bonne façon de le décrire. Malheureusement, la documentation et les génériques dans la signature est assez compliqué, donc c'est très difficile à apprendre l'utilisation il suffit de lire les docs. Ensuite, vous pouvez voir un exemple et d'aller "aha!" J'ai de l'espoir.
OriginalL'auteur PM 77-1 | 2014-04-24
Vous devez vous connecter pour publier un commentaire.
Sotirios Delimanolis réponse indique comment résoudre les problèmes, mais j'ai quelques petites choses à ajouter.
Si vous avez déjà une classe qui implémente Comparateur, vous n'avez pas besoin d'utiliser une méthode de référence pour sa méthode compare (). Vous pouvez simplement passer une instance de celui-ci directement, puisque max() prend une référence à un élément de Comparaison:
ou
Cependant, le combinateur fonctions sur le Comparateur généralement de rendre inutile d'avoir une classe qui implémente Comparateur. Par exemple, vous pouvez vous débarrasser de la
forTestComparator
classe entièrement et il suffit de faire ceci:ou si
forTest
ont eu l'évidence getValue() la méthode, on peut réécrire le flux de max() comme suit:En outre, si vous vouliez faire
forTest
mettre en œuvre lesComparable
interface, vous pourriez faire ceci:et la manière d'utiliser le max() Comparable est:
Deux style notes:
Je déconseille vivement à l'aide
orElse(null)
sur les instances deOptional
. C'est autorisé, mais il est probable que son objet principal de rénovation de l'utilisation de nouvelles Java 8 Api dans le code qui s'attend à null pour indiquer l'absence de valeur. ÉviterorElse(null)
si vous le pouvez, depuis cette les forces de l'appelant pour vérifier la valeur null. Au lieu de cela, substituer une valeur réelle pour remplacer un absent de la valeur, ou le retour de laOptional
lui-même à l'appelant, de sorte que l'appelant peut s'appliquer quelle que soit la politique qu'il veut.Je vous recommande de coller les conventions de nommage Java de majuscules, minuscules des noms de classe. Les noms de classe
forTest
etforTestComparator
rendre ce code genre de difficile de travailler avec, car ils n'ont pas look comme les noms de classe.OriginalL'auteur Stuart Marks
forTestComparator#compare
est une méthode d'instance. Vous avez besoin d'un instance méthode de référence, par opposition à unstatic
méthode de référence que vous avez.Quelque chose comme
ou le chemin le plus long (votre classe n'a pas l'état de l'instance, de sorte que vous n'avez pas vraiment à la référence)
Voir la Java tutoriel sur la méthode des références ici.
Note de côté, ce
résout dans un
forTest
valeur. Vous avez besoin de changer le type de retour de votre méthode.Un merci tout spécial pour la note de côté. Je n'ai pas pris conscience de son importance au premier abord.
OriginalL'auteur Sotirios Delimanolis