Я применил метод equals в объекте Person с @annotation, однако, когда я создаю объект в своем основном классе и проверяю его на объекты List of Person, он не возвращает правильный индекс. В нем говорится, что они оба равны 1, но это должно быть 1 и 3.
Задача:
Проверьте, существует ли в моем списке "Энди Бернард", и если да, отобразите индекс объектов.
import java.util.ArrayList;
import java.util.List;
public class Person {
private String firstName;
private String lastName;
public Person(String firstName,String lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
@Override
public String toString() {
return String.format(this.firstName + " " + this.lastName);
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result
+ ((firstName == null) ? 0 : firstName.hashCode());
result = prime * result
+ ((lastName == null) ? 0 : lastName.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Person other = (Person) obj;
if (firstName == null) {
if (other.firstName != null)
return false;
} else if (!firstName.equals(other.firstName))
return false;
if (lastName == null) {
if (other.lastName != null)
return false;
} else if (!lastName.equals(other.lastName))
return false;
return true;
}
private static List<Person> deletePeople = new ArrayList<>();
public static void main(String[] args) {
addPerson("Micheal","Scott");
addPerson("Andy","Bernard");
addPerson("Micheal","Scott");
addPerson("Andy","Bernard");
display();
}
public static void addPerson(String firstname, String lastname) {
Person createPerson = new Person(firstname,lastname);
deletePeople.add(createPerson);
}
public static void display() {
Person checkPerson = new Person("Andy","Bernard");
for (Person display : deletePeople) {
if(display.equals(checkPerson)) {
System.out.println((display.getFirstName() + " " +
display.getLastName() + " " + deletePeople.indexOf(display)));
}
}
}
}
indexOf
возвращает индекс первого вхождения, который является одним и тем же (в соответствии с методом equals) в List. Вот почему вы видите, что и один напечатан.
Возвращает индекс первого вхождения указанного элемента в этом списке или -1, если этот список не содержит этот элемент. Более формально возвращает наименьший индекс я такой, что (o == null? Get (i) == null: o.equals(get (i))) или -1, если такого индекса нет.
И вы можете увидеть реализацию (для ArrayList
, но ту же идею для LinkedList
за исключением того, что вы итерации других узлов):
229 public int indexOf(Object o) {
230 if (o == null) {
231 for (int i = 0; i < size; i++)
232 if (elementData[i]==null)
233 return i;
234 } else {
235 for (int i = 0; i < size; i++)
236 if (o.equals(elementData[i]))
237 return i;
238 }
239 return -1;
240 }
Если вы хотите напечатать связанный индекс, вы можете использовать счетчик, который вы увеличиваете на каждой итерации.
int index = 0;
for (Person display : deletePeople) {
if(display.equals(checkPerson)){
System.out.println((display.getFirstName() + " " + display.getLastName() + " " + index));
}
index++;
}
Это также было бы возможно со стандартом для цикла.
for(int i = 0; i < deletePeople.size(); i++){
Person display = deletePeople.get(i);
if(display.equals(checkPerson)){
System.out.println((display.getFirstName() + " " + display.getLastName() + " " + i));
}
}
Однако будьте осторожны с последней реализацией, потому что если базовое представление списка является LinkedList
сложность вышеуказанного цикла будет O(n^2)
вместо O(n)
.
indexOf()
вы печатаете первый индекс, который соответствует, а не текущий индекс. Если вам интересно отслеживать свою позицию в списке, лучше всего это сделать вручную, поэтому вместо цикла for-each:
for(Object o : ls) {
// the syntax is nice, but we don't have an easy way to
// tell how far into the list we are
System.out.println(o);
}
Вместо этого используйте простой цикл:
for(int i = 0; i < ls.size(); i++) {
Object o = ls.get(i);
// Now we have access to the object *and* its index
System.out.println(i+": "+o);
}
Кроме того, в вашем коде есть несколько простых исправлений, если вы простите меня, вот несколько советов:
Избегайте разрешать null
в ваших объектах - редко имеет значение null
фактически, и позволяет ему заставить все вызывающие коды выполнять нулевые проверки везде.
public Person(String firstName,String lastName) {
if(firstName == null || lastName == null) {
throw new NullPointerException("First/Last name cannot be null");
}
this.firstName = firstName;
this.lastName = lastName;
}
Используйте String.format()
правильно или просто избегайте этого. Ваш текущий метод toString()
вызывает String.format(this.firstName + " " + this.lastName)
, который на самом деле ничего не делает; вы можете просто вернуть конкатенированную строку без String.format()
. Кроме того, вы можете правильно использовать функциональные возможности формата:
String.format("%s %s", firstName, lastName);
Воспользуйтесь классом Java 7 Objects
для ваших методов hashCode()
и equals()
:
@Override
public int hashCode() {
return Objects.hash(firstName, lastName);
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Person other = (Person) obj;
return Objects.equals(firstName, other.firstName) &&
Objects.equals(lastName, other.lastName);
}
deletePeople
? Где это заявлено?