Подтвердить что ты не робот

Компаратор с двойным типом

Я написал следующий код:

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() вернуть double, а не int. Проблема в том, что мое поле getX является двойным. Как я могу решить эту проблему?

4b9b3361

Ответ 1

Вам не нужно возвращать 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;
    }    
}

Ответ 2

Я предлагаю вам использовать встроенный метод 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 равно всем.

Ответ 3

Метод 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;
}

Но поскольку сравнение значений с плавающей запятой всегда затруднительно, вы должны сравнивать в определенном диапазоне (см. этот вопрос), примерно так:

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

Ответ 4

Так как Java 1.8 вы также можете использовать

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

Ответ 5

Я просто хочу расширить ответ Питера Лоури на JDK 8, если вы сделаете так:

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

Вы можете легко определить этот компаратор с помощью выражения лямбда

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

Еще лучше, вы могли бы использовать ссылку на члену следующим образом:

Double::compare

Ответ 6

Используйте 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;
    }

Ответ 7

Ну, вы можете умножить эти двойные значения на соответствующий коэффициент перед преобразованием в целое число, например. в вашем случае с момента его единственного десятичного разряда, поэтому 10 будет хорошим фактором;

return (int)(p1.getY()*10 - p2.getY()*10);