Оператор If в цикле for возвращает true только один раз?

#java #for-loop #if-statement

#java #for-цикл #if-statement

Вопрос:

 private List<Double[]> bestPoints(List<Double[]> includedPoints) {
        List<Double[]> bestPoints = new ArrayList<Double[]>();
        int a = includedPoints.size();
        for (int i = 0; i < a; i  ) {
            Double[] tempPoint = includedPoints.get(i);

            if (tempPoint[2] == maxCount) {
                bestPoints.add(new Double[] {tempPoint[0], tempPoint[1]});
            }
        }

        return bestPoints;
    }
  

В этом случае

 a = 17
maxCount = 2.0
  

и

tempPoint[2] в этом случае 2.0 каждый раз

но отладчик показывает, что

bestPoints.add(новый Double[] {Точка [0], точка[1]});

Выполняется только один раз, как если бы оператор if не был true? Почему?

Комментарии:

1. Вы уверены , что это 2.0, а не 1.999999999 …? Использование == on double — очень рискованная операция.

2. Он не использует == для double … он использует его на Double , в чем проблема. Это сравнение ссылочного значения.

Ответ №1:

Скорее всего, вы выполняете ссылку equals, а не сравнение equals. При использовании версий числовых типов, написанных заглавными буквами, вам следует использовать one.equals(two) .

Убедитесь, что значение tempPoint[2] является точным 2.0 . В качестве double очень возможно, что они близки, но не равны.

Вам также может показаться, что использовать цикл foreach проще для выполнения:

 private List<Double[]> bestPoints(List<Double[]> includedPoints) {
    List<Double[]> bestPoints = new ArrayList<Double[]>();
    for (Double[] tempPoint : tempPoints) {
        if (tempPoint[2] == maxCount) {
             bestPoints.add(new Double[] { tempPoint[0], tempPoint[1] });
        }
    }

    return bestPoints;
}
  

Если значения всегда являются целыми числами, то приведите их перед проверкой равенства (например, (long)tempPoint[2] == (long)maxCount ). Если вам нужны точные совпадения из double s, то продолжайте то, что вы делаете (после обеспечения надлежащего типа проверки равенства, зависящей от maxCount), но если вам нужны совпадения, близкие (если десятичные дроби вызывают беспокойство, а не предопределенные константы), тогда используйте значение epsilon:

 public static boolean doubleEquals(double val1, double val2, double epsilon)
{
    return Math.abs(val1 - val2) < epsilon;
}

public static boolean doubleEquals(double val1, double val2)
{
    return doubleEquals(val1, val2, 1e-5);
}
  

Очевидно, укажите значение epsilon, которое имеет смысл для вас.

Ответ №2:

В условии, которое вы пытаетесь сопоставить ссылкам объекта Double, вместо этого вам следует использовать if(временная точка [2].compareTo(maxCount)==0).

Ответ №3:

Поскольку вы используете «java.lang.Двойной». Они являются объектами. Предполагая, что maxCount также равен Double

Для сравнения двух объектов используйте

equals()

 d1.equals(d2)
  

другой вариант — использовать «compareTo())

 d1.compareTo(d2)
  

значение 0, если d1 численно равно d2; значение меньше 0, если d1 численно меньше d2; и значение больше 0, если d1 численно больше d2.

Подробнее читайте здесь http://download.oracle.com/javase/6/docs/api/java/lang/Double.html

Ответ №4:

Для сравнения двух примитивных значений double используйте метод compare(double d1, double d2) класса Double. Это статический метод. Он возвращает 0, если оба значения равны, возвращает значение меньше 0, если d1 меньше, чем d2, и возвращает значение больше, чем 0, если d1 больше, чем d2.

Ответ №5:

Если вы совершенно уверены, что это tempPoint[2] всегда new Double(2.0) , а if maxCount является примитивным double, например, double maxCount = 2.0; вместо Double maxCount = new Double(2.0) , условие if должно быть выполнено успешно. В противном случае вы можете использовать if (tempPoint[2].equals(maxCount)) вместо этого, который делает if (tempPoint[2].doubleValue() == maxCount.doubleValue())