J'ai écrit le code suivant:
public class NewClass2 implements Comparator<Point>
{
public int compare(Point p1, Point p2)
{
return (int)(p1.getY() - p2.getY());
}
}
Si je disais avoir deux doubles nombres, 3.2 - 3.1
, la différence devrait être 0.1
. Cependant, lorsque je transforme le nombre en int, la différence est 0
, ce qui est incorrect.
J'ai donc besoin de compare()
pour renvoyer un double, pas un int. Le problème est que mon champ getX
est un double. Comment puis-je résoudre ce problème?
Vous n'avez pas besoin de retourner double
.
L'interface Comparator
sert à établir un ordre pour les éléments comparés. Avoir des champs qui utilisent double
est sans importance pour cet ordre.
Votre code est bon.
Désolé, je me suis trompé en relisant la question, voici ce dont vous avez besoin:
public class NewClass2 implements Comparator<Point> {
public int compare(Point p1, Point p2) {
if (p1.getY() < p2.getY()) return -1;
if (p1.getY() > p2.getY()) return 1;
return 0;
}
}
Je vous suggère d'utiliser la méthode intégrée Double.compare (). Si vous avez besoin d'une plage pour que les valeurs doubles soient égales, vous pouvez utiliser chcek pour cela en premier.
return Double.compare(p1.getY(), p2.gety());
ou
if(Math.abs(p1.getY()-p2.getY()) < ERR) return 0;
return Double.compare(p1.getY(), p2.gety());
Le problème avec <et> est que NaN renverra false dans les deux cas, ce qui entraînera un traitement potentiellement incohérent. par exemple. NaN est défini comme n'étant égal à rien, même si toutefois dans les solutions de @ suihock et @ Martinho, si l'une ou l'autre valeur est NaN, la méthode retournera 0 à chaque fois, ce qui implique que NaN est égal à tout.
Depuis Java 1.8, vous pouvez également utiliser
Comparator.comparingDouble(p -> p.getY())
La méthode compare
devrait renvoyer une int
. C'est un nombre qui est soit:
Vous n'avez pas besoin de renvoyer une double
. Vous devez renvoyer une int
pour implémenter l'interface Comparator
. Il vous suffit de renvoyer la int
correcte, conformément aux règles que j'ai décrites ci-dessus.
Vous ne pouvez pas simplement lancer depuis int, car, comme vous l'avez dit, une différence de 0,1 aboutira à 0. Vous pouvez simplement faire ceci:
public int compare(Point p1, Point p2)
{
double delta= p1.getY() - p2.getY();
if(delta > 0) return 1;
if(delta < 0) return -1;
return 0;
}
Mais comme la comparaison des valeurs en virgule flottante est toujours gênante, vous devriez comparer dans une certaine plage (voir cette question ), quelque chose comme ceci:
public int compare(Point p1, Point p2)
{
double delta = p1.getY() - p2.getY();
if(delta > 0.00001) return 1;
if(delta < -0.00001) return -1;
return 0;
}
Je veux juste développer la réponse de Peter Lawrey sur JDK 8, si vous le faites comme ceci:
public class NewClass2 implements Comparator<Point> {
public int compare(Point p1, Point p2) {
return Double.compare(p1.getY(), p2.gety());
}
}
Vous pouvez définir ce comparateur en utilisant une expression lambda assez facilement
(Point p1,Point p2) -> Double.compare(p1.getY(), p2.gety())
Mieux encore, vous pouvez utiliser une référence de membre comme celle-ci:
Double::compare
Il est si important dans Java 8 que vous choisissez celui que vous voulez:
Comparator<someClass> cp = (a, b) -> Double.compare(a.getScore(), b.getScore());
Comparator<someClass> cp = Comparator.comparing(someClass::getScore);
Comparator<someClass> cp = Comparator.comparingDouble(someClass::getScore);
Utilisez Double.compare(/**double value 1*/, /**double value 2*/);
avec un nouveau comparateur pour la valeur double de votre classe de modèle.
public static List<MyModel> sortByDouble(List<MyModel> modelList) {
Collections.sort(modelList, new Comparator<MyModel>() {
@Override
public int compare(MyModels1, MyModels2) {
double s1Distance = Double.parseDouble(!TextUtils.isEmpty(s1.distance) ? s1.distance : "0");
double s2Distance = Double.parseDouble(!TextUtils.isEmpty(s2.distance) ? s2.distance : "0");
return Double.compare(s1Distance, s2Distance);
}
});
return modelList;
}
Eh bien, vous pouvez multiplier ces valeurs doubles par un facteur approprié avant de convertir en entier, par exemple. dans votre cas puisque sa seule décimale, alors 10 serait un bon facteur;
return (int)(p1.getY()*10 - p2.getY()*10);
Double min = Arrays.stream(myArray).min(Double::compare).get();