2015-12-20 2 views
-1

Я изучаю объектно-ориентированное программирование на Java в своей школе, и мне пришлось выполнять упражнение для сравнения Кругов.Метод класса равнозначен

Я имел круг класса с этими

частного Int идентификатор;

приватная строка bgColor;

приватная строка fgColor;

И внутри него мне пришлось использовать метод Equals для сравнения двух кругов (с помощью этих трех атрибутов): окружность равен другой окружности, если ее радиус и BG и fgColor одинаков.

public boolean equals(Object obj) { 
    boolean found; 
    if (obj == null) { 
     found = false; 
    } 
    if (getClass() != obj.getClass()) { 
     found = false; 
    } 
    final Circle other = (Circle) obj; 
    if (Double.doubleToLongBits(this.radius) == Double.doubleToLongBits(other.radius)) { 
     //found = false; 

     if (Objects.equals(this.bgColor, other.bgColor)) { 
      //found = false; 

      if (Objects.equals(this.fgColor, other.fgColor)) { 
       return true; 
      }//end if fgColor 
      else{ 
       found = false; 
      } 
     }//end if bgcolor 
     else{ 
      found = false; 
     } 
    }//end if radius 
    else{ 
     found = false; 
    } 

    return found; 
} 

Но мой учитель сказал мне, что код выше «запутанный», но я не понимаю, почему.

Вы знаете лучшее решение?

Мой учитель хочет, чтобы мы Folow эту структуру (этот случай только сравнивая одно свойство):

public boolean equals (Object obj) 
{ 
     boolean b; 

     if(obj == null) 
     { 
       b = false; 
     } 
     else 
     { 
       if(this == obj)//same object 
       { 
         b = true; 
       } 
       else 
       { 
         if(obj instanceof Book)     
         { 
           Book other = (Book) obj; 
           b = (this.id == other.id); 
         } 
         else 
         { 
           b = false; 
         } 
       } 
     } 

     return b; 
} 
+0

Да, это так. Очень смущает. –

+3

@ Tiny Это было бы столь же запутанным, как и его код выше. – Kayaman

+0

Вместо того, чтобы иметь отдельные 'else' и' ifs', используйте конструкцию 'else if'. Нет никакого преимущества в том, что у вас так много брекетов. – Kayaman

ответ

3

Это о самой краткой версии (при условии, что радиус и цвет не может быть пустым). Нулевая проверка OBJ позаботятся в InstanceOf теста:

public boolean equals(Object obj) { 

    if(! (obj instanceof Circle)) 
     return false; 

    Circle rhs = (Circle)obj; 
    return Double.compare(radius, rhs.radius) == 0 && 
     bgColor.equals(rhs.bgColor) && 
     fgColor.equals(rhs.fgColor); 
} 
+0

Кто бы ни запустил исходную версию этого пару минут назад: это был промах ключа« enter ». У меня есть все основания полагать, что это правильно. Пожалуйста, будьте любезны, чтобы убедиться, что вы все еще считаете, что это заслуживает ниспроверки (и любезно скажите почему). – NietzscheanAI

+0

http://stackoverflow.com/questions/17898266/why-cant-we-use-to-compare-two-float-or-double-numbers – bhspencer

+0

Это не скомпилируется. Нет переменной «другое». Парм называется obj. – bhspencer

0

Если вы используете IDE (я надеюсь, что вы делаете), вероятно, он имеет возможность генерировать код равен метод. Eclipse, создает что-то вроде:

@Override 
public boolean equals(Object obj) { 
    if (this == obj) 
     return true; 
    if (obj == null) 
     return false; 
    if (getClass() != obj.getClass()) 
     return false; 
    Circle other = (Circle) obj; 
    if (bgColor == null) { 
     if (other.bgColor != null) 
      return false; 
    } else if (!bgColor.equals(other.bgColor)) 
     return false; 
    if (fgColor == null) { 
     if (other.fgColor != null) 
      return false; 
    } else if (!fgColor.equals(other.fgColor)) 
     return false; 
    if (Double.doubleToLongBits(radius) != Double.doubleToLongBits(other.radius)) 
     return false; 
    return true; 
} 

И не забудьте Реализует метод Hashcode когда вы реализуете метод равно и vicecersa.

+0

Спецификация не требует сравнения идентификаторов «Круг равен другому кругу, если его радиус и bg и fgColor одинаковы». – bhspencer

0

Вместо того, чтобы иметь один оператор возврата, используйте несколько точек возврата для упрощения кода. Таким образом, вам не нужны дополнительные логические переменные, чтобы удержать результаты предыдущих условий.

public class Circle { 
    public double radius; 
    public String bgColor; 
    public String fgColor; 

    public boolean equals(Object obj) { 
     if (obj == null) { 
      return false; 
     } else if (obj instanceof Circle) { 
      Circle other = (Circle) obj; 
      if (Double.compare(this.radius, other.redius) == 0 
        && compareStrings(this.fgColor, other.fgColor) 
        && compareStrings(this.bgColor, other.bgColor)) { 
       return true; 
      } else { 
       return false; 
      } 
     } else { 
      return false; 
     } 
    } 

    private boolean compareStrings(String a, String b) { 
     if (a == null && b == null) { 
      return true; 
     } else if (a != null) { 
      return a.equals(b); 
     } else if (b != null) { 
      return b.equals(a); 
     } 
     return false; 
    } 
} 

Это решение допускает возможность, что либо Струнного fgColor или BGColor может быть нулевым, не бросая NPE. Сравнение String было извлечено в его собственную функцию, чтобы облегчить читаемость и уменьшить путаницу.

+0

Если 'fgColor' или' bgColor' являются нулевыми, ваш код будет вызывать 'NullPointerException' – tddmonkey

+0

. Это хорошая точка – bhspencer

+0

Исправлено, чтобы избежать возможного NPE, если строки цвета равны нулю. – bhspencer

0
public boolean equals(Object obj) { 
     if (obj == null) { 
      return false; 
     } 
     if (getClass() != obj.getClass()) { 
      return false; 
     } 
     // its a Circle so its safe to case 
     Circle other = (Circle)obj; 

     // equals ONLY if 3 conditions are met 
     if (radius == other.getRadius() && 
      bgColor.equals(other.getBgColor()) && 
      fgColor.equals(other.getFgColor())){ 
      return true; 
     } 
     return false; 
    } 
+0

Это вызовет NPE, если bgColor имеет значение null. Также рассмотрите http://stackoverflow.com/questions/17898266/why-cant-we-use-to-compare-two-float-or-double-numbers – bhspencer

0

В качестве последующей деятельности по итогам моего предыдущего ответа:

Написание равенства метод, который работает правильно в присутствии подклассов крайне нетривиальная (см комментарии Джошуа Блоха в пункте 8 `Эффективное Java «).

Действительно, до относительно недавнего времени не было широко известного единого метода для этого.

В 2009 году статья "How to Write an Equality Method in Java" Мартин Одерски, Лекс Лоун и Билл Веннерс показывают, что это может быть достигнуто с помощью метода «canEqual».

+1

Это должен быть комментарий, а не ответ. – bhspencer

+1

@bhspencer Для этого кажется немного длинным. Кроме того, комментарии по моему предыдущему ответу касались «рекомендуемого продолжения в чате». – NietzscheanAI

+0

Это должно быть отредактировано в ваш первоначальный ответ, так как этот ответ не дает ответа на вопрос сам по себе. – Cypher