2016-04-13 3 views
-2

У меня есть этот класс== против равен метод двойников

public class Point { 
    private Double[] coordinates; 
    private int dimension; 

    public Point(Double[] coordinates) { 
     dimension = coordinates.length; 
     this.coordinates = new Double[dimension]; 

     for(int i = 0; i < dimension; i++) 
      this.coordinates[i] = coordinates[i]; 


    } 

    public Double getCoord(int n) { 
     if(n < 0 || n > dimension -1){ 
      throw new RuntimeException("error de coordenadas"); 
     } 
     return coordinates[n]; 
    } 
    public int getDim() { 
     return dimension; 
    } 

    public boolean equals(Object p1){ 
     if((p1 instanceof Point)){ 
      Point p = (Point) p1; 
      int n = p.getDim(); 
      if(getDim() == n) 
      { 
       for(; n > 0; n--) 
       { 
        if(Double.valueOf(this.getCoord(n-1)) != Double.valueOf(p.getCoord(n-1))) // <------- BAD LINE! 
        { 
         System.out.println("Checking coord " + (n-1)); 
         System.out.println("Coord " + (n-1) + " p = " + Double.valueOf(this.getCoord(n-1))); 
         System.out.println("Coord " + (n-1) + " p2 = " + Double.valueOf(p.getCoord(n-1))); 
         return false; 
        } 
       } 
      } 
      return true; 
     } 
     return false; 
    } 
} 

И эта главная

public class FigureTest { 
    public static void main(String[] args){ 
     Double[] coord1 = {2.0,3.3}; 
     Double[] coord2 = {2.0,3.3}; 
     Point p = new Point(coord1); 
     Point q = new Point(coord2); 
     System.out.println(p.equals(q)); 
    } 
} 

Я не могу понять, почему это p.equals(q) возвращает ложь! Он находится внутри if(Double.valueOf(..., но затем печатает, что обе координаты равны. То же самое, если я удалю Double.valueOf. Единственный способ, которым это работало, это когда я положил ! if(this.getCoord(n-1).equal(p.getCoord(n-1)), но я не понимаю, почему другие не работают.

+1

Вы понимаете разницу между 'p.equals (q)' и 'p == q'? (Что делает '==' при использовании с объектами?) – Radiodef

+0

Почему вы не используете просто 'Arrays.equals()' в методе 'Point # equals()'? –

+0

@Radiodef, если '.equals' не был перезаписан, тогда он будет таким же, как' == ': сравнение ссылок, не так ли? Else, будет вызываться метод equals класса 'p'. – YoTengoUnLCD

ответ

3

Double.valueOf возвращает Doubleобъект, не примитивный двойной.

Вы выполняете контрольную проверку (!=). Поэтому, даже если Double.valueOf(getCoords(n-1)) вернул одинаковое числовое значение для обоих вызовов, разные объекты будут обертывать номера, поэтому проверка! = Была бы правдой, в результате чего ваши равны для возврата false.

Вот краткий пример:

public static void main(String[] args){ 
    System.out.println(Double.valueOf(5) == Double.valueOf(5)); 
} 

Обратите внимание, как он возвращает false. Это потому, что == является контрольной проверкой, и каждый другой объект возвращается каждый раз, когда вы вызываете Double.valueOf. Так что, когда вы делаете

Double.valueOf(...) != Double.valueOf(...) 

Это проверка возвращает истину, поскольку valueOf вызовы не возвращать один и тот же объект. Вот почему проверка вашего кода возвращает true, в результате чего equals возвращается false.


Чтобы исправить это, вы могли бы ...

Замените свой != на проверку .equals, которая будет сравнивать числовые значения, а не ссылки.

Double.valueOf(...).equals(Double.valueOf(...)); 

Это возвращает true если оба одни и те же числовые значения.

Или вы могли бы использоватьdoubleValue() при вызове getCoord:

getCoord(n-1).doubleValue() != other.getCoord(n-1).doubleValue() 

Это позволит избежать избыточного создания Double объектов.

+1

Или используйте 'this.getCoord (n-1) .doubleValue()! = P.getCoord (n-1) .doubleValue()' для сравнения примитивов –

-2

Для того, чтобы это работало ;:

p.equals(q) 

вы должны сохранить договор между Hashcode и равна и переопределить правильно оба из них: equals И hashcode в классе Point, и когда я пишу правильно я имею в виду конкретно это:

Пожалуйста, обратитесь к этому question, если вы не знаете, почему или что вам не нужно

Double.valueOf(this.getCoord(n-1)) != Double.valueOf(p.getCoord(n-1)) 

, если члены класса Point двойники, то вы правы, когда вы сравните эти двойники в качестве критериев, чтобы решить, если p1.equals (p2)

, но в соответствии с documentation of the class Double, статический метод Double.compare(this.getCoord(n-1)),p.getCoord(n-1) должен быть используйте для сравнения 2 двухместных контента.

поэтому я рекомендую делать в методе equals некоторые похожи на эту

if(Double.compare(this.getCoord(n-1)),p.getCoord(n-1)!=0)) 
+1

почему они должны реализовать 'hashCode()' ??? Здесь нет хеш-коллекции. И они * внедрили * equals(), и вопрос в том, «почему он не работает». –

+1

@SashaSalauyou - это просто хорошая практика переопределить hashCode(), когда вы переопределяете equals(), хотя в этом случае это не требуется. Но в целом автору класса необходимо обеспечить, чтобы оба метода были предоставлены, если один из них. – Madhusudhan

+2

@ user3493289 согласен, это хорошая практика. Но никак не связан с вопросом. Отвечает состояниям «вам нужно», как будто их реализация решит проблему. –