web-dev-qa-db-fra.com

Comparateur avec type double

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?

36
user472221

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;
    }    
}
63
dteoh

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.

93
Peter Lawrey

Depuis Java 1.8, vous pouvez également utiliser 

Comparator.comparingDouble(p -> p.getY())
10
Jan Dolejsi

La méthode compare devrait renvoyer une int. C'est un nombre qui est soit:

  • Moins que zéro, si la première valeur est moins que la seconde;
  • Equal à zéro, si les deux valeurs sont égal;
  • Supérieur à zéro, si la première valeur est supérieure à la seconde;

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;
}
8

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
2
Miguel Durazo

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);
1
QM.py

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;
    }
1
Ready Android

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);
0
HasnainMamdani
Double min  = Arrays.stream(myArray).min(Double::compare).get();
0
Stan Sokolov