2016-12-14 52 views
1

我使用了Set:HashSet和TreeSet.I的2個實現。我添加了10個元素來設置和通過set中的包含方法查找對象。我看到包含方法遍歷所有對象,儘管它找到了元素。爲了性能原因,我困惑了。它是如此,我如何防止它?HashSet如何「包含」方法工作?

我有一個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; 
    } 
} 

}

而在主類別i添加10 Person對象,然後調用由一組第一個元素包含方法:

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 
+0

沒有什麼奇怪的鑼。 'hashCode'(你的打印語句所在的地方)在插入過程中被地圖調用。 – teppic

回答

6

您的equals()方法有誤。無論對方是誰,它都會返回真實。

它不尊重equals()的合同,因爲相同的對象應該有相同的hashCode,並且hashCode是該人的ID。因此,具有不同ID的兩個人具有不同的hashCode,但仍然相等。

也就是說,你的測試顯示hashCode()被執行了10次。但它不會被執行。它由add()執行。每次向對象添加對象時,都會使用它的hashCode()來知道哪個存儲桶應該容納該對象。

0

它不遍歷所有元素。爲每個對象打印哈希碼的原因是因爲在插入集合時需要計算哈希碼。

0

前10個打印可能是用於插入代碼,最後一個用於包含調用。我希望這可能會讓你感到困惑。