Comparator with double type

旧时模样 提交于 2019-11-27 08:12:39

You don't need to return double.

The Comparator interface is used to establish an ordering for the elements being compared. Having fields that use double is irrelevant to this ordering.

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

I suggest you use the builtin method Double.compare(). If you need a range for double values to be equal you can use chcek for that first.

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. e.g. 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.

Since Java 1.8 you can also use

Comparator.comparingDouble(p -> p.getY())
R. Martinho Fernandes

The method compare should return an 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. You must return an int to implement the Comparator interface. You just have to return the correct int, according to the rules I outlined above.

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:

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:

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

(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:

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*/); 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;

return (int)(p1.getY()*10 - p2.getY()*10);
Double min  = Arrays.stream(myArray).min(Double::compare).get();
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!