2016-12-14 7 views
1

私はSet:HashSetとTreeSetの2つの実装を使用しました。setからのcontainsメソッドを使ってオブジェクトを設定および検索するために10個の要素を追加しました。メソッドが含まれていることがわかります。要素を見つけましたが、すべてのオブジェクトを繰り返します。それはそうで、どうすればそれを防ぐことができますか?HashSetは "contains"メソッドの動作をどのようにしますか?

私は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オブジェクトを追加し、呼び出しはセットの最初の要素によってメソッドが含まれています

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'(あなたのprintステートメントがどこにあるか)は、挿入中にマップによって呼び出されます。 – teppic

答えて

6

equals()メソッドが間違っています。他の人物が何であれ真実を返します。

等しいオブジェクトは等しいhashCodeを持ち、hashCodeはその人物のIDなので、equals()、BTWの契約は尊重しません。したがって、異なるIDを持つ2人の人は異なるhashCodeを持っていますが、それでも同じです。

つまり、あなたのテストでは、hashCode()が10回実行されることが示されています。しかし、それはによって実行されません。それはadd()によって実行されます。オブジェクトをセットに追加するたびに、hashCode()は、オブジェクトを保持するバケットを知るために使用されます。

0

すべての要素を反復しません。ハッシュコードが各オブジェクトに対して出力される理由は、セットに挿入するときにハッシュコードを計算する必要があるためです。

0

最初の10枚のプリントは、おそらく挿入コード用であり、最後のプリントは含まれています。それがあなたを混乱させるかもしれないものであることを願っています。

関連する問題