Java ArrayList IndexOf-Поиск Индекса Объекта
допустим у меня есть класс
public class Data{
public int k;
public int l;
public Data(int k, int l){
this.k = k;
this.l = l;
}
public boolean equals(Date m){
if(this.k == m.k && this.l = m.l)
return true;
return false;
}
}
и я добавляю несколько объектов данных в ArrayList:
ArrayList<Data> holder = new ArrayList<Data>;
Data one = new Data(0,0);
Data two = new Data(0,4);
Data three = new Data(0,5);
почему indexOf не находит этого?:
holder.indexOf(new Data(0,4)); //returns -1
является ли indexOf лучше, чем проходить через весь список массивов самостоятельно? Или я что-то упускаю.
4 ответов
на indexOf()
метод тут пройдите весь список. Вот выдержка из исходного кода Java 7:
public int indexOf(Object o) {
if (o == null) {
for (int i = 0; i < size; i++)
if (elementData[i]==null)
return i;
} else {
for (int i = 0; i < size; i++)
if (o.equals(elementData[i]))
return i;
}
return -1;
}
было бы лучше позволить Java пройти через это, чем написать это самостоятельно. Просто убедитесь, что ваш equals
метод достаточен при поиске нужного объекта. Вы также захотите переопределить hashCode()
как хорошо.
Я не буду писать свой equals
метод, но я бы рекомендовал вам по крайней мере:
- проверить значение null
- проверьте, совпадают ли сравниваемые экземпляры
- вам не нужно делать
if(boolean_expr) { return true; }
; просто верните логическое выражение. - убедитесь, что вы на самом деле переопределение
equals
метод-подпись этого требует
подпись equals
метод неверен. Вы не переопределяете equals
на Object
, но просто перегружает его.
чтобы переопределить поведение equals
метод Object
, ваша подпись должна точно совпадать с той, что в Object
. Попробуйте это:
public boolean equals(Object o) {
if(!(o instanceof Data)) return false;
Data other = (Data) o;
return (this.k == other.k && this.l == other.l);
}
кроме того, как предлагали другие, это хорошая идея, чтобы переопределить hashCode
метод также для вашего объекта для правильной работы в коллекциях на основе карт.
ответ от Макото право. То же самое я бы сказал. Но у вас есть некоторые ошибки в вашем коде выше.
- вы написали " public boolean equals (Date m){". Я думаю, вы имели в виду данные вместо даты.
- вы написали " если(это.k = = m.k & & это.l = m.l)". Второе условие в запросе if должно быть "==".
на ваш вопрос: Ответ Макото-одно из решений. Мое решение-использовать помощь eclipse для автоматической генерации хэш-код и равна методы. Вот так:
public class Data {
// your class code here
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + k;
result = prime * result + l;
return result;
}
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (!(obj instanceof Data)) {
return false;
}
Data other = (Data) obj;
if (k != other.k) {
return false;
}
if (l != other.l) {
return false;
}
return true;
}
}
по соглашению вы хотите переопределить хэш-код также при переопределении equals
вы, скорее всего, обнаружите, что indexOf использует метод hashcode для соответствия объекту, а не equals
Если вы используете eclise для редактирования кода-eclipse создаст для вас хороший метод equals и hashcode из меню "source".