it-swarm.com.de

Komparator mit Doppeltyp

Ich habe folgenden Code geschrieben:

public class NewClass2 implements Comparator<Point>
{
    public int compare(Point p1, Point p2)
    {
        return (int)(p1.getY() - p2.getY());
    }
}

Wenn ich zwei doppelte Zahlen, 3.2 - 3.1, habe, sollte der Unterschied 0.1 sein. Wenn ich die Zahl in ein int konvertiere, endet der Unterschied jedoch als 0, was nicht korrekt ist.

Ich brauche also compare(), um ein double zurückzugeben, kein int. Das Problem ist, mein Feld getX ist doppelt. Wie kann ich dieses Problem lösen?

36
user472221

Sie müssen keine double zurückgeben.

Die Comparator-Schnittstelle wird verwendet, um eine Reihenfolge für die zu vergleichenden Elemente festzulegen. Die Verwendung von Feldern, die double verwenden, ist für diese Reihenfolge nicht relevant.

Ihr Code ist in Ordnung.

Entschuldigung, ich habe mich geirrt, als ich die Frage noch einmal gelesen habe.

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

Ich schlage vor, dass Sie die Builtin-Methode Double.compare () verwenden. Wenn Sie einen Bereich für doppelte Werte benötigen, können Sie zuerst chcek verwenden.

return Double.compare(p1.getY(), p2.gety());

oder

if(Math.abs(p1.getY()-p2.getY()) < ERR) return 0;    
return Double.compare(p1.getY(), p2.gety());

Das Problem bei der Verwendung von <und> ist, dass NaN in beiden Fällen false zurückgibt, was möglicherweise zu einer inkonsistenten Behandlung führt. z.B. NaN wird als nicht gleich definiert, selbst jedoch in @ suihocks und @ Martinhoes Lösungen. Wenn einer der Werte NaN ist, gibt die Methode jedes Mal 0 zurück, was bedeutet, dass NaN alles ist.

93
Peter Lawrey

Seit Java 1.8 kannst du auch verwenden 

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

Die Methode compare sollte eine int zurückgeben. Es ist eine Zahl, die entweder

  • Weniger als Null, wenn der erste Wert Weniger als der zweite ist;
  • Equal zu Null, wenn die beiden Werte Equal sind;
  • Größer als Null, wenn der erste Wert Größer als der zweite ist;

Sie brauchen nicht need, um eine double zurückzugeben. Sie müssen geben eine int zurück, um die Comparator-Schnittstelle zu implementieren. Sie müssen nur die korrekte int gemäß den oben beschriebenen Regeln zurückgeben.

Sie können nicht einfach von int aus wirken, da, wie Sie sagten, ein Unterschied von 0,1 zu 0 führt. Sie können dies einfach tun:

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

Da der Vergleich von Fließkommawerten jedoch immer mühsam ist, sollten Sie innerhalb eines bestimmten Bereichs vergleichen (siehe diese Frage ).

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

Ich möchte nur die Antwort von Peter Lawrey auf JDK 8 erweitern, wenn Sie es so machen:

public class NewClass2 implements Comparator<Point> {
    public int compare(Point p1, Point p2) {
        return Double.compare(p1.getY(), p2.gety());
    }    
}

Sie können diesen Vergleicher ganz leicht mit einem Lambda-Ausdruck definieren

(Point p1,Point p2) -> Double.compare(p1.getY(), p2.gety())  

Besser noch, Sie könnten eine Memberreferenz wie folgt verwenden:

Double::compare
2
Miguel Durazo

Es ist in Java 8 so überzeugend, wählen Sie jeden aus, wie Sie möchten:

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

Verwenden Sie Double.compare(/**double value 1*/, /**double value 2*/); mit einem neuen Comparator für den Doppelwert Ihrer Modellklasse.

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

Nun, Sie können diese doppelten Werte vor der Umwandlung in eine ganze Zahl mit einem geeigneten Faktor multiplizieren, z. In Ihrem Fall wäre es nur eine Dezimalstelle, also 10 wäre ein guter Faktor.

return (int)(p1.getY()*10 - p2.getY()*10);
0
HasnainMamdani
Double min  = Arrays.stream(myArray).min(Double::compare).get();
0
Stan Sokolov