53

我写了以下代码:

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

如果我说有两个双数,3.2 - 3.1,则差应该是0.1。但是,当我将数字转换为 int 时,差异最终为0,这是不正确的。

因此,我需要compare()返回一个双精度,而不是一个整数。问题是,我的getX领域是双重的。我怎么解决这个问题?

4

10 回答 10

128

我建议你使用内置方法 Double.compare()。如果您需要一个使双精度值相等的范围,您可以首先使用 chcek 。

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

或者

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

使用 < 和 > 的问题是 NaN 在这两种情况下都会返回 false,从而导致处理可能不一致。例如,NaN 被定义为不等于任何东西,甚至它本身,但是在@suihock 和@Martinho 的解决方案中,如果任一值为 NaN,则该方法每次都将返回 0,这意味着 NaN 等于一切。

于 2010-11-22T08:58:34.133 回答
75

你不需要返回double

Comparator接口用于为被比较的元素建立排序。具有使用double的字段与此排序无关。

你的代码很好。

对不起,我错了,再次阅读问题,这就是你需要的:

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;
    }    
}
于 2010-11-22T03:36:32.343 回答
17

从 Java 1.8 开始,您还可以使用

Comparator.comparingDouble(p -> p.getY())
于 2016-12-12T22:17:16.257 回答
10

该方法compare应该返回一个int. 它是一个数字,可以是:

  • 小于零,如果第一个值小于第二个;
  • 等于零,如果两个值相等
  • 大于零,如果第一个值大于第二个;

无需返回double. 您必须返回一个int来实现Comparator接口。int根据我上面概述的规则,您只需要返回正确的 。

你不能简单地从 int 转换,就像你说的那样,0.1 的差异将导致 0。你可以简单地这样做:

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

但是由于浮点值的比较总是很麻烦,所以应该在一定范围内进行比较(见this question),如下所示:

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;
}
于 2010-11-22T03:34:52.227 回答
6

在 Java 8 中非常方便,随意选择任何人:

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);
于 2018-06-28T13:35:44.277 回答
5

如果您这样做,我只想扩展 JDK 8 上的 Peter Lawrey 回答:

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

您可以很容易地使用 lambda 表达式定义此比较器

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

更好的是,您可以使用这样的成员引用:

Double::compare
于 2016-03-01T20:22:19.537 回答
1

Double.compare(/**double value 1*/, /**double value 2*/);与新的比较器一起使用您的模型类双精度值。

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;
    }
于 2017-05-08T11:41:42.613 回答
0

好吧,您可以在转换为整数之前将这些双精度值乘以适当的因子,例如。在您的情况下,因为它只有一位小数,所以 10 将是一个很好的因素;

return (int)(p1.getY()*10 - p2.getY()*10);
于 2014-05-16T22:39:56.627 回答
0
Double min  = Arrays.stream(myArray).min(Double::compare).get();
于 2018-01-29T16:45:08.680 回答
0
int compare(Double first, Double second) {
    if (Math.abs(first - second) < 1E-6) {
        return 0;
    } else {
        return Double.compare(first, second);
    }
}
于 2020-01-21T09:58:13.560 回答