2016-12-14 53 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个打印可能是用于插入代码,最后一个用于包含调用。我希望这可能会让你感到困惑。