2

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

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

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());
}

従業員クラスは:

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);
    }
}
4

5 に答える 5

3

HashSet含まれているオブジェクトの変更に反応することを意図したものではありません。実際、ドキュメントは、可変オブジェクトをセットに追加して変更することに対して警告しています。

Setインターフェイスのドキュメントから:

注:可変オブジェクトをセット要素として使用する場合は、細心の注意を払う必要があります。オブジェクトがセット内の要素であるときに、等しい比較に影響を与える方法でオブジェクトの値が変更された場合、セットの動作は指定されません。この禁止の特殊なケースは、セットがそれ自体を要素として含むことは許可されないということです。

(もう1つのポイントはHashSet、メンバーequals()hashCode()メソッドを使用することです。つまり、これらのメソッドを実装しなかった場合、同じオブジェクトへの2つの参照でない限り、2つは等しくなりませんEmployee。)編集では、実装したことを示します。それ。EmployeeEmployee

実用的な「とにかくこれを行うとどうなりますか?」(b / caは、挿入したエントリをダミーオブジェクトにマップするものとして実装されています)のソースコードをHashMap見ると、変数を追加および削除した場合にのみサイズが更新され、テーブルは容量を増やすために再ハッシュされ、等価性チェックはありません。そのため、重複するオブジェクトは、最初に実行すべきではなかったことを実行することによって中断したセットにとどまります。HashSetHashMap

于 2012-05-04T04:01:26.567 に答える
3

そして、クラス内のメソッドhashCode()equals()メソッドをどのように定義しましたか?Employeeさらに、aのコントラクトにはHashSet、セット内の2つの可変オブジェクトが突然同じハッシュを持つ場合の対処方法が指定されていないため、どちらか一方がセットから自動的に削除されるとは限りません。

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

可変オブジェクトをセット要素として使用する場合は、細心の注意を払う必要があります。オブジェクトがセット内の要素であるときに、等しい比較に影響を与える方法でオブジェクトの値が変更された場合、セットの動作は指定されません。この禁止の特殊なケースは、セットがそれ自体を要素として含むことは許可されないということです。

于 2012-05-04T04:02:39.963 に答える
0

size()セット内の要素の数を返します。セットを呼び出してセットを変更しないので、セットe1.setName()のサイズは同じままです。

于 2012-05-04T04:01:26.233 に答える
0

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

于 2012-05-04T04:01:38.433 に答える
0

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

于 2012-05-04T04:04:16.267 に答える