[英]How does HashSet “contains” method work?
我使用Set:HashSet和TreeSet的2種實現。我添加了10個元素以通過set中的contains方法設置和查找對象。我看到contains方法會迭代所有對象,盡管它找到了element。出於性能原因,我感到困惑。為什么所以,我該如何預防呢?
我有一個Person類:
public class Person implements Comparable<Person>{
private int id;
private String name;
public Person() {
}
public Person(int id, String name) {
this.id = id;
this.name = name;
}
//getter and setters
@Override
public int hashCode() {
System.out.println("hashcode:" + toString());
return this.id;
}
@Override
public boolean equals(Object obj) {
System.out.println("equals:" + toString());
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final Person other = (Person) obj;
return true;
}
@Override
public String toString() {
return "Person{" + "id=" + id + ", name=" + name + '}';
}
@Override
public int compareTo(Person o) {
System.out.println("compare to:"+getId()+" "+o.getId());
if(o.getId() == getId()){
return 0;
}else if(o.getId()>getId()){
return -1;
}else {
return 1;
}
}
}
在主類中,我添加10 Person對象,然后通過set的第一個元素調用contains方法:
import beans.Person;
import java.util.Date;
import java.util.HashSet;
import java.util.Set;
public class Main {
public static void main(String[] args) {
Set<Person> people = new HashSet<>();
for (int i = 0; i < 10; i++) {
people.add(new Person(i, String.valueOf(i)));
}
Person find = people.iterator().next();
if (people.contains(find)) {
System.out.println("here"+find.getName());
}
}
}
結果:
hashcode:Person{id=0, name=0} <--here element has been found but it continues
hashcode:Person{id=1, name=1}
hashcode:Person{id=2, name=2}
hashcode:Person{id=3, name=3}
hashcode:Person{id=4, name=4}
hashcode:Person{id=5, name=5}
hashcode:Person{id=6, name=6}
hashcode:Person{id=7, name=7}
hashcode:Person{id=8, name=8}
hashcode:Person{id=9, name=9}
hashcode:Person{id=0, name=0}<-- second check
here:0
您的equals()
方法錯誤。 無論其他人是什么,它都會返回true。
它不遵守equals()
,BTW的約定,因為相等的對象應具有相等的hashCode,並且hashCode是人的ID。 因此,具有不同ID的兩個人具有不同的hashCode,但仍然相等。
也就是說,您的測試顯示hashCode()被執行10次。 但是它不是由contains()
執行的。 它由add()
執行。 每次將對象添加到集合中時,都會使用其hashCode()
來知道哪個存儲桶應容納該對象。
它不會迭代所有元素。 為每個對象打印哈希碼的原因是因為在插入到集合中時需要計算哈希碼。
前十個打印可能用於插入代碼,后一個打印用於contains調用。 我希望這可能會使您感到困惑。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.