2012-05-04 8 views
2

HashSetに2つの異なるオブジェクト(変更可能)を追加した後、setterを呼び出してオブジェクトの値を変更すると(同じにする)、サイズはhashSetの2になりますSetを作成した後にHashsetを作成するオブジェクトが同じになる

私は同じ理由を理解することはできませんよ。

public static void main(String[] args) { 
     Employee e = new Employee(); 
     e.setName("Amit"); 
     Employee e1 = new Employee(); 
     e1.setName("Jitender"); 
     Set<Person> hashSet = new HashSet<Person>(); 
     hashSet.add(e); 
     hashSet.add(e1); 
     // size of set is >>2 
     System.out.println("size of set is >>" + hashSet.size()); 
     e1.setName("Amit"); 
     // updated size of set is >>2 
     System.out.println("updated size of set is >>" + hashSet.size()); 
} 

Employeeクラスは次のとおりです。

public class Employee extends Person { 

    public Employee() { 
    } 

    public Employee(String name) { 
     this.name = name; 
    } 

    String name; 

    public String getName() { 
     return name; 
    } 

    public void setName(String name) { 
     this.name = name; 
    } 

    @Override 
    public int hashCode() { 
     // TODO Auto-generated method stub 
     return name.hashCode(); 
    } 

    @Override 
    public boolean equals(Object obj) { 
     Employee e = (Employee) obj; 
     return this.name.equals(e.name); 
    } 
} 

答えて

3

HashSetは、それに含まれるオブジェクトの変更に反応することを意図していません。実際、ドキュメントには、変更可能なオブジェクトをセットに追加して変更することが警告されています。 Set interface documentationから

注:可変オブジェクトがセット要素として使用されている場合には細心の注意を払わなければなりません。オブジェクトがセット内の要素であるときにequalsの比較に影響するように、オブジェクトの値が変更された場合、セットの動作は指定されません。この禁止の特別な場合は、セットがそれ自身を要素として含むことは許されないということです。

(もう一つのポイントは、あなたのEmployeeため、これらのメソッドを実装していなかった場合、彼らは同じに2つの参照されている場合を除き、2つのEmployee sが等しくならないことを意味し、HashSetはメンバーのequals()hashCode()メソッドを使用していることですEmployeeオブジェクトです。)編集では、それを実装したことが示されます。

実用的には「とにかくこれを行うとどうなりますか?注:source code of HashMap(b/ca HashSetは、入力したエントリをダミーオブジェクトにマップするHashMapとして実装されています)を参照すると、変数の追加と削除時にのみサイズが更新されます。テーブルは容量を増やすために再ハッシュされ、平等チェックはありませんあなたの重複したオブジェクトは、あなたが最初にやったことがないはずのことをやってしまったそのセットにとどまります。

+0

もう1つのことを教えてください。「この禁止の特殊なケースは、セットがそれ自身を要素として含むことは許されない」ということです...... ......それは良いアイデアや例外ではないことを意味します(私はそれを追加しようとしましたが、それは例外を与えません) –

+0

それだけで自分自身にセットを加えることは悪い考えです。例外をスローしたりエラーを発生させたりすることはありません。正しく機能しません。 – trutheality

+0

もう一度説明していただき、ありがとうございます。 –

0

集合の要素数を返しますsize()e1.setName()を呼び出してセットを変更しないので、セットのサイズは変わりません。

0

2つの異なるオブジェクトをセットに追加しました。それらの値が同じであっても、それらは異なるオブジェクトです。

3

EmployeeクラスでhashCode()equals()の方法をどのように定義しましたか?さらに、HashSetの契約の中には、セット内の2つの可変オブジェクトが突然同じハッシュを持つ場合、何をするかを指定するものはありません。どちらか一方が自動的にセットから削除されると考えることはできません。

また、Setのドキュメントからこのnoteの点に注意してください。

変更可能なオブジェクトがセット要素として使用されている場合には細心の注意を払わなければなりません。オブジェクトがセット内の要素であるときにequalsの比較に影響するように、オブジェクトの値が変更された場合、セットの動作は指定されません。この禁止の特別な場合は、セットがそれ自身を要素として含むことは許されないということです。

0

これらは、2つの異なるEmployee.classのインスタンスを使用して作成されました。したがって、プロパティ名と同じ値を持つ場合でも、それらはまだ異なるオブジェクトです。もちろん、等号がpropery名に基づいているように、Employee.classではハッシュと等価がオーバーライドされていない限り。

関連する問題