[英]Java: Why Doesn’t My Equals Method Work?
我使用@annotation在我的Person對象中實現了equal的方法,但是,當我在主類中創建一個對象並將其與我的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)));
}
}
}
}
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循環也是可能的。
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(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);
}
此外,您可以在代碼中進行很多簡單的清理,如果您會原諒我的話,這里有一些建議:
避免在您的對象中允許null
很少有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);
為您的hashCode()
和equals()
方法利用Java 7的Objects
類:
@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); }
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.