Содержит метод ArrayList
У меня есть объект
class A {
private Long id;
private String name;
public boolean equals(Long v) {
return this.id.equals(v);
}
}
и ArrayList этих объектов.
Я хочу, чтобы проверить, содержит ли этот список какой-либо объект по полю объекта.
Например:
ArrayList<A> list = new ArrayList<A>(); if (list.contains(0L)) {...}
но переопределенный метод Equals мне не помогает. Что я делаю неправильно?
Спасибо вам
UPDATE
И должен ли я переопределить метод hashcode()?
Ответы
Ответ 1
вот какой код, который может продемонстрировать, как это работает:
import java.util.ArrayList;
class A {
private Long id;
private String name;
A(Long id){
this.id = id;
}
@Override
public boolean equals(Object v) {
boolean retVal = false;
if (v instanceof A){
A ptr = (A) v;
retVal = ptr.id.longValue() == this.id;
}
return retVal;
}
@Override
public int hashCode() {
int hash = 7;
hash = 17 * hash + (this.id != null ? this.id.hashCode() : 0);
return hash;
}
}
public class ArrayList_recap {
public static void main(String[] args) {
ArrayList<A> list = new ArrayList<A>();
list.add(new A(0L));
list.add(new A(1L));
if (list.contains(new A(0L)))
{
System.out.println("Equal");
}
else
{
System.out.println("Nah.");
}
}
}
Во-первых, существует переопределение метода equals (Object o). Тогда есть переопределение hashCode(). Также обратите внимание, что проверка экземпляра A на равных будет гарантировать, что вы не пытаетесь сравнивать разные объекты.
Это должно сделать трюк! Надеюсь, это помогло! Приветствия:)
Ответ 2
Вы не переопределили метод в своем классе. Чтобы переопределить, параметры метода также должны быть одного типа.
он должен быть
public boolean equals(Object o) {
}
где, как и в вашем случае,
public boolean equals(Long o) {
}
вам, вероятно, нужно это сделать
public boolean equals(Object o)
{
if (o == null) return false;
if (o == this) return true; //if both pointing towards same object on heap
A a = (A) o;
return this.id.equals(a.id);
}
Ответ 3
Что я делаю неправильно?
Вы не переопределяете. Вы перегружаетесь.
Метод contains
вызывает метод equals
с сигнатурой equals(Object)
, поэтому этот (новый) метод, который вы добавили, не будет вызываться.
Другая проблема заключается в том, что ваш метод equals
имеет неправильную семантику для contains
. Метод contains
должен сравнивать this
с объектом, который может быть членом списка. Ваш список не содержит объектов Long
. Он содержит объекты типа A
.
Теперь вы можете уйти от этого... если вы используете типы сырого списка... но то, что вы пытаетесь сделать, это нарушение контракта API и плохая практика. Лучшим решением является итерация и проверка элементов списка явно.
И должен ли я переопределить метод hashcode()?
Если вы переопределите equals(Object)
, вы также должны переопределить hashcode()
.
Здесь не будет никакой разницы, но важно, если вы когда-либо помещаете объекты A
в хешированные структуры данных. И поскольку вы не знаете, что следующий парень собирается делать с вашим кодом, это хорошая практика, чтобы убедиться, что equals(Object)
и hashcode()
имеют совместимую семантику.