简体   繁体   English

双型比较器

[英]Comparator with double type

I have written the following code:我编写了以下代码:

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

If I let's say have two double numbers, 3.2 - 3.1 , the difference should be 0.1 .如果我假设有两个双数, 3.2 - 3.1 ,差异应该是0.1 When I cast the number to an int, however, the difference ends up as 0 , which is not correct.但是,当我将数字转换为 int 时,差异最终为0 ,这是不正确的。

I therefore need compare() to return a double, not an int.因此,我需要compare()返回双精度值,而不是整数。 The problem is, my getX field is a double.问题是,我的getX字段是双getX的。 How can I solve this problem?我怎么解决这个问题?

I suggest you use the builtin method Double.compare().我建议您使用内置方法 Double.compare()。 If you need a range for double values to be equal you can use chcek for that first.如果您需要双精度值的范围相等,您可以先使用 chcek。

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

or或者

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

The problem with using < and > is that NaN will return false in both cases resulting in a possibly inconsistent handling.使用 < 和 > 的问题是 NaN 在这两种情况下都将返回 false,从而导致处理可能不一致。 eg NaN is defined as not being equal to anything, even itself however in @suihock's and @Martinho's solutions, if either value is NaN the method will return 0 everytime, implying that NaN is equal to everything.例如,NaN 被定义为不等于任何东西,即使是它本身,但在@suihock 和@Martinho 的解决方案中,如果其中一个值为 NaN,则该方法每次都将返回 0,这意味着 NaN 等于一切。

You don't need to return double .您不需要返回double

The Comparator interface is used to establish an ordering for the elements being compared. Comparator接口用于为被比较的元素建立排序。 Having fields that use double is irrelevant to this ordering.使用double字段与此排序无关。

Your code is fine. 你的代码没问题。

Sorry, I was wrong, reading the question again, this is what you need:抱歉,我错了,再次阅读问题,这就是您需要的:

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

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

Comparator.comparingDouble(p -> p.getY())

The method compare should return an int .方法compare应该返回一个int It is a number that is either:它是一个数字,可以是:

  • Less than zero, if the first value is less than the second;小于零,如果第一个值小于第二个;
  • Equal to zero, if the two values are equal ;等于零,如果两个值相等;
  • Greater than zero, if the first value is greater than the second;大于零,如果第一个值大于所述第二;

You don't need to return a double .不需要返回double You must return an int to implement the Comparator interface.必须返回一个int来实现Comparator接口。 You just have to return the correct int , according to the rules I outlined above.您只需要根据我上面概述的规则返回正确的int

You can't simply cast from int, as, like you said, a difference of 0.1 will result in 0. You can simply do this:你不能简单地从 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;
}

But since comparison of floating-point values is always troublesome, you should compare within a certain range (see this question ), something like this:但是由于浮点值的比较总是很麻烦,您应该在一定范围内进行比较(请参阅此问题),如下所示:

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

I just want to expand on Peter Lawrey answer on JDK 8, if you do it like this:我只想扩展 Peter Lawrey 在 JDK 8 上的回答,如果你这样做的话:

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

You could define this comparator using a lambda expression pretty easily你可以很容易地使用 lambda 表达式定义这个比较器

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

Better yet, you could use a member reference like this:更好的是,您可以使用这样的成员引用:

Double::compare

It is so convinent in Java 8, choose anyone just as you wish:它在 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);

Use Double.compare(/**double value 1*/, /**double value 2*/);使用Double.compare(/**double value 1*/, /**double value 2*/); with a new Comparator for your model class double value.为您的模型类双值使用新的比较器。

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

Well, you could multiply those double values by an appropriate factor before converting into integer, for eg.好吧,您可以在转换为整数之前将这些双精度值乘以适当的因子,例如。 in your case since its only one decimal place so 10 would be a good factor;在您的情况下,因为它只有一位小数,所以 10 将是一个很好的因素;

return (int)(p1.getY()*10 - p2.getY()*10);
Double min  = Arrays.stream(myArray).min(Double::compare).get();
int compare(Double first, Double second) {
    if (Math.abs(first - second) < 1E-6) {
        return 0;
    } else {
        return Double.compare(first, second);
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM