Я пытаюсь переопределить метод equals в Java. У меня есть класс, People который в основном имеет 2 поля данных name и age. Теперь я хочу переопределить equals метод, чтобы я мог проверять между объектами 2 People.
Мой код выглядит следующим образом
publicbooleanequals(People other){ boolean result; if((other == null) || (getClass() != other.getClass())){ result = false; } // end if else{ PeopleotherPeople= (People)other; result = name.equals(other.name) && age.equals(other.age); } // end else
return result; } // end equals
Но когда я пишу, age.equals(other.age) это выдает мне ошибку, поскольку метод equals может сравнивать только строку, а возраст - целое число.
Решение
Я использовал == оператор, как было предложено, и моя проблема решена.
Переведено автоматически
Ответ 1
//Written by K@stackoverflow publicclassMain {
/** * @param args the command line arguments */ publicstaticvoidmain(String[] args) { // TODO code application logic here ArrayList<Person> people = newArrayList<Person>(); people.add(newPerson("Subash Adhikari", 28)); people.add(newPerson("K", 28)); people.add(newPerson("StackOverflow", 4)); people.add(newPerson("Subash Adhikari", 28));
for (inti=0; i < people.size() - 1; i++) { for (inty= i + 1; y <= people.size() - 1; y++) { booleancheck= people.get(i).equals(people.get(y));
- СБОРКА ВЫПОЛНЕНА УСПЕШНО (общее время: 0 секунд)
Ответ 2
Введение новой сигнатуры метода, которая изменяет типы параметров, называется перегрузкой:
publicbooleanequals(People other){
Здесь People все иначе, чем Object.
Когда сигнатура метода остается идентичной сигнатуре его суперкласса, это называется переопределением, а @Override аннотация помогает различать их во время компиляции:
@Override publicbooleanequals(Object other){
Не видя фактического объявления age, трудно сказать, почему появляется ошибка.
Ответ 3
Я не уверен в деталях, поскольку вы опубликовали не весь код, но:
не забудьте также переопределить hashCode()
в качестве типа аргумента equals метод должен иметь Object, а не People. В данный момент вы перегружаете, а не переопределяете метод equals, что, вероятно, не то, что вы хотите, особенно учитывая, что вы проверяете его тип позже.
вы можете использовать instanceof, чтобы проверить, что это объект People, например if (!(other instanceof People)) { result = false;}
equals используется для всех объектов, но не для примитивов. Я думаю, вы имеете в виду, что age - это int (примитив), и в этом случае просто используйте ==. Обратите внимание, что целое число (с заглавной буквы 'I') - это объект, который следует сравнивать с equals.
Пункт 10: Соблюдайте общий контракт при переопределении equals
Согласно эффективной Java, переопределение equals метода кажется простым, но есть много способов сделать это неправильно, и последствия могут быть ужасными. Самый простой способ избежать проблем - не переопределять equals метод, и в этом случае каждый экземпляр класса равен только самому себе. Это правильно, если выполняется любое из следующих условий:
Каждый экземпляр класса по своей сути уникален. Это верно для таких классов, как Thread, которые представляют активные сущности, а не значения. Реализация equals, предоставляемая Object, имеет точно правильное поведение для этих классов.
Классу не нужно предоставлять тест на “логическое равенство”. Например, java.util.regex.Pattern мог переопределить equals, чтобы проверить, представляют ли два экземпляра шаблона в точности одно и то же регулярное выражение, но разработчики не подумали, что клиентам понадобится такая функциональность. В этих обстоятельствах реализация equals, унаследованная от Object, идеальна.
Суперкласс уже переопределил equals, и поведение суперкласса подходит для этого класса. Например, большинство реализаций Set наследуют свою реализацию equals от AbstractSet, реализации List - от AbstractList, а реализации Map - от AbstractMap.
Класс является закрытым или закрытым для пакета, и вы уверены, что его метод equals никогда не будет вызван. Если вы не склонны к риску, вы можете переопределить метод equals, чтобы убедиться, что он не будет вызван случайно:
equals Метод реализует отношение эквивалентности. Он обладает следующими свойствами:
Рефлексивный: для любого ненулевого ссылочного значения x, x.equals(x) должно возвращаться значение true.
Симметричный: для любых ненулевых ссылочных значений x и y, x.equals(y) должно возвращать true тогда и только тогда, когда y.equals(x) возвращает true.
Транзитивный: для любых ненулевых ссылочных значений x, y, z, если x.equals(y) возвращает true и y.equals(z) возвращает true, то x.equals(z) должен возвращать true.
Согласовано: для любых ненулевых ссылочных значений x и y множественные вызовы x.equals(y) должны последовательно возвращать true или постоянно возвращать false, при условии, что информация, используемая в сравнениях equals, не изменена.
Для любого ненулевого ссылочного значения x, x.equals(null) должно возвращаться false.
Вот рецепт высококачественного метода equals:
Используйте оператор ==, чтобы проверить, является ли аргумент ссылкой на этот объект. Если да, верните true . Это всего лишь оптимизация производительности, но ее стоит выполнить, если сравнение потенциально дорогостоящее.
Используйте оператор instanceof, чтобы проверить, имеет ли аргумент правильный тип. Если нет, верните false . Обычно правильный тип - это класс, в котором встречается метод. Иногда это какой-то интерфейс, реализованный этим классом. Используйте интерфейс, если класс реализует интерфейс, который уточняет контракт equals, чтобы разрешить сравнения между классами, реализующими интерфейс. Этим свойством обладают интерфейсы коллекций, такие как Set, List, Map и Map.Entry.
Приведите аргумент к правильному типу. Поскольку этому приведению предшествовал тест instanceof, его успех гарантирован.
Для каждого “значимого” поля в классе проверьте, совпадает ли это поле аргумента с соответствующим полем этого объекта. Если все эти тесты завершились успешно, верните true; в противном случае верните false . Если тип на шаге 2 является интерфейсом, вы должны получить доступ к полям аргумента через методы интерфейса; если тип является классом, вы можете получить доступ к полям напрямую, в зависимости от их доступности.
Для примитивных полей, тип которых не является float or double, используйте == оператор для сравнений; для полей ссылки на объект вызывайте equals метод рекурсивно; для float полей используйте статический Float.compare(float, float) метод; а для double полей используйте Double.compare(double, double). Специальная обработка полей float и double становится необходимой из-за существования Float.NaN, -0.0f и аналогичных значений double ; Хотя вы могли бы сравнивать float и double поля со статическими методами Float.equals и Double.equals, это повлекло бы за собой автоматическую блокировку при каждом сравнении, что привело бы к снижению производительности. Для array полей применяйте эти рекомендации к каждому элементу. Если каждый элемент в поле массива значим, используйте один из Arrays.equals методов.
Некоторые поля ссылки на объект могут законно содержать null. Чтобы избежать возможности NullPointerException, проверьте такие поля на равенство с помощью статического метода Objects.equals(Object, Object).
// Class with a typical equals method
publicfinalclassPhoneNumber {
privatefinalshort areaCode, prefix, lineNum;
publicPhoneNumber(int areaCode, int prefix, int lineNum) {