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?
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;
}
}
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.
Seit Java 1.8 kannst du auch verwenden
Comparator.comparingDouble(p -> p.getY())
Die Methode compare
sollte eine int
zurückgeben. Es ist eine Zahl, die entweder
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
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);
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;
}
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);
Double min = Arrays.stream(myArray).min(Double::compare).get();