Почему при таком решении не проходит второе требования, кто-нибудь может объяснить?
package com.javarush.task.pro.task10.task1010;
ipackage com.javarush.task.pro.task10.task1010;
import java.util.Objects;
/*
Два айфона
*/
public class Iphone {
private String model;
private String color;
private int price;
public Iphone(String model, String color, int price) {
this.model = model;
this.color = color;
this.price = price;
}
@Override
public boolean equals(Object obj){
if(this==obj)
return true;
if(obj == null)
return false;
if(!(obj instanceof Iphone))
return false;
Iphone iphone1 = (Iphone)obj;
if(this.price !=iphone1.price)
return false;
if(this.color == null && this.model == null)
return iphone1.color == null && iphone1.model == null;
if(this.color.equals(iphone1.color) == this.model.equals(iphone1.model))
return true;
return false;
}
public static void main(String[] args) {
Iphone iphone1 = new Iphone("X", "Black", 999);
Iphone iphone2 = new Iphone("X", "Black", 999);
System.out.println(iphone1.equals(iphone2));
}
}
задача под названием "Два айфона"
Требования:
• В классе Iphone должен быть переопределен метод public boolean equals(Object).
• Метод equals должен возвращать true для двух равных объектов типа Iphone и false — для разных.
• Метод equals должен возвращать false, если в него передали null.
Gregory2.0
20 уровень
Объясните требования
Комментарии (17)
- популярные
- новые
- старые
Для того, чтобы оставить комментарий Вы должны авторизоваться
Денис Enterprise Java Developer
6 сентября 2023, 09:42
Каждое из полей, модель или цвет может быть равно нуллу и по отдельности, не обязательно одновременно. Так например если одно из полей нулл, а второе нет ты получишь NullPointerException
+2
wan-derer.ru
6 сентября 2023, 08:27
1. Оформи код соответствующим тэгом
2. Эт чё?
0
Денис Enterprise Java Developer
6 сентября 2023, 09:45
> 2. Эт чё?
Это весьма специфическая попытка проверить два условия сразу, при том автор забыл, что false == false тоже вернёт true :)
Ну и учитывая весьма спорную проверку на нуллы парой строк выше это еще и генератор NPE
+1
Gregory2.0
6 сентября 2023, 10:07
Суть в том что при изменении параметров одного из Iphone они становятся разными, валидатор выдает False, но пишет что второе условие не соблюдено?
0
Денис Enterprise Java Developer
6 сентября 2023, 10:14
Ну смотри, я тебе уже в принципе написал в чём ошибка.
1. Модель и цвет могут быть нулами по отдельности. Проводя проверку через && ты требуешь, чтобы они были нулами одновременно, очевидно так бывает не всегда
2. Из-за того что ты пропускаешь нуллы через свой фильт, на строчке
у тебя будет вылетать NullPointerException
3. Даже если там не будет NPE, при этом и цвет и модель будут отличаться, при одинаковой цене ты все равно вернёшь true, что очевидно не верно.
Резюмируя, код работает не верно, какие именно пункты валидации там не проходят не столь важно.
Так же не забывай, что есть такое понятие как equals hashcode контракт, у него есть ряд свойств, в частности:
1. Симметрия, если a = b то b = a
2. Рефлексия, a всегда должно быть равно самому себе.
3. Транзитивность. если a = b и b = c то a = c 0
Денис Enterprise Java Developer
6 сентября 2023, 10:23
Один из простых вариантов решения здесь следующий:
Не обязательно обращаться к собственным полям объекта через this, очевидно, что если у Класса есть нестатическое свойство и нестатический метод работающий с ним, никаких дополнительных подсказок не нужно, за исключением того случая когда у тебя есть переменная с таким же именем, как например в случае с конструктором.
Приведенный код выполняет простую проверку, он проверяет равенство полей друг другу это случится в двух случаях, если поля равны нулл (что допустимо) либо ссылаются на один и тот же объект в памяти, что технически тоже возможно. Если это условие не выполнено проходит вторая проверка, что поле исходного объекта не равно нулл и оно равно по значению такому же полю проверяемого объекта. Здесь true будет только в одном случае, если поля равны по значению. Если поле исходного объекта равно нулл и мы уже находимся во второй проверке, очевидно что поле проверяемого объекта нуллом не является и как следсвтие поля не равны, дальше проверять смысла нет мы идём в конец метода и возвращаем false.
Так вот через две вложенные проверки мы добрались до цены, это обычный integer, проверяется через ==, ну а как мы знаем равенство возвращает булево значение, т.е. если мы добрались до проверки цены мы можем ее результат и вернуть, на этот момент два других поля у нас уже точно равны, а значит от того равны ли цены зависи и равнство объектов друг другу. +1
Gregory2.0
6 сентября 2023, 10:29
Спасибо, дело было в этой строчке:
if(this.color == null && this.model == null)
return iphone1.color == null && iphone1.model == null;
Переписал ее на вот это как по условию и написано при передаче null в equals ответ должен быть false :
if(this.color == null || this.model == null)
return false;
0
Денис Enterprise Java Developer
6 сентября 2023, 10:41
Ну проблемную строчку ты указал правильно, а переписал нет. Почему именно установка поля в null должна возвращать false?
Разве это разные объекты? Ну чисто логически. 0
Gregory2.0
6 сентября 2023, 10:47
Потому что требования задачи "Метод equals должен возвращать false, если в него передали null."
Вот кстати насчет разности этих объектов, я так понял разные, потому они созданы каждый по отдельности , раз готовый метод equals, без моего метода выдает false
+1
Gregory2.0
6 сентября 2023, 10:51
Я так понял у объектов разные ссылки, а у параметров одинаковые, потому что в моем методе equals сравниваются именно ссылки параметров, а не методов
0
Денис Enterprise Java Developer
6 сентября 2023, 11:01
> если в него передали null.
Что именно эта строка по твоему означает?) Действительно, если сделать iphone.equals(null) то метод должен вернуть false, это логично. Но как это относится к полям этого самого объекта? Любой объект в Java может быть null'ом, это нужно воспринимать как данность и корректно обрабатывать.
Если ты сделаешь model.equals(null) это тоже вернёт false, но если model сама равна null то сделав такую проверку твой код упадёт. У null нельзя вызвать метод.
Тем не менее, как я писал в комментарии выше,
метод equals должен вернуть true на этих объектах, при том в обоих направлениях, как iphone1.equals(iphone2) так и iphone2.equals(iphone1)
> Вот кстати насчет разности этих объектов, я так понял разные
Нет, просто базовый метод очень простой, именно по этому он и базовый, чтобы в каждом кастомном классе программист его переопределял. Только программист может решить что является условием равенства, а что нет. Какие поля для объекта ценны, а какие не очень.
Почему ты сравниваешь строки через equals? Потому что для тебя как человека, пользователя, заказчика, важно что эта строка собой представляет, а не где она лежит в памяти. Для любого человека "Вася" и "Вася" это две одинаковых строки, даже если они лежат на разных компьютерах :) А в некоторых случаях одинаковы даже эти два Васи: "Вася" и "вАсЯ". 0
Gregory2.0
6 сентября 2023, 11:25
Насчет null понял, а вот насчет equals и ссылок я правильно описал получается у этих двух объектов разные ссылки в памяти, поэтому базовый метод и выдает false ?
0
Денис Enterprise Java Developer
6 сентября 2023, 11:30
Правильно, если ты заглянешь в класс Object то увидишь весьма примитивную реализацию :)
Т.е. в сущности он просто возвращает результат сравнения по ссылке. Именно по этому, ни для каких объектов базовый метод использовать не получится и его нужно переопределять если ты планируешь объекты сравнивать. 0
Gregory2.0
6 сентября 2023, 11:46
Благодарю за разъяснения)👍
0
Gregory2.0
6 сентября 2023, 12:06
Такой вопрос а почему тогда при базовом методе такой ответ :
String a = new String("Привет");
String b = new String("Привет");
System.out.println(a == b); false
System.out.println(a.equals(b)); true
0
Gregory2.0
6 сентября 2023, 12:08
Извиняюсь невнимательно читал статью😅
+1
Gregory2.0
6 сентября 2023, 12:08
Вопрос исчерпан
0