我使用@annotation在Person对象中实现了equal的方法,但是,当我在主类中创建一个对象并根据我的List of Person对象进行检查时,它不会返回正确的索引。它说它们都是1,但它应该是1和3。
目的:
检查我的列表中是否存在“Andy Bernard”,如果存在,则显示对象的索引。
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)));
}
}
}
}
答案 0 :(得分:4)
indexOf
返回List中第一次出现的索引(根据equals方法)。这就是为什么你看到两个都打印出来的。
返回指定元素第一次出现的索引 此列表,如果此列表不包含该元素,则返回-1。更多 正式地,返回最低的索引i,使得(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)
。
答案 1 :(得分:0)
通过调用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循环:
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);
}
此外,您可以在代码中进行相当多的简单清理,如果您原谅我,请参阅以下建议:
Avoid allowing null
in your objects - 很少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);
的连接字符串。或者,您可以正确使用格式功能,如下所示:
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);
}
方法利用Java 7的Objects
课程:
{{1}}