12

非常に基本的な質問があります。java.util.Set は、追加されたオブジェクトが重複しているかどうかをいつチェックしますか?

以下のようなモデル クラスがあるため、equals メソッドと hashcode メソッドの両方をオーバーライドします。

public class SampleModel implements Comparable {
    private String name;

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

    // Setter and Getter omitted
    @Override
    public boolean equals(Object arg0) {
        boolean eq = false;

        if (arg0 instanceof SampleModel
                && this.name.equalsIgnoreCase(((SampleModel) arg0).name)) {
            eq = true;
        }
        return eq;
    }

    @Override
    public int compareTo(Object arg0) {
        return this.name.compareTo(((SampleModel) arg0).name);
    }

    @Override
    public int hashCode() {
        return this.name.length();
    }
}

次に、HashSet でモデル オブジェクトを使用する方法を示します。

    SampleModel s1 = new SampleModel("Satya");
    SampleModel s2 = new SampleModel("Katti");

    Set<SampleModel> samSet = new HashSet<SampleModel>();
    System.out.println(samSet.add(s1));
    System.out.println(samSet.add(s2));

    s2.setName("Satya");
    System.out.println(s2.getName());
    System.out.println(s1 + ", " + s2);

equality 句に従って、オブジェクトは同じで等しいですが、HashSet には重複が含まれます。

イコールまたはハッシュコードに関して違反が発生していますか? このコードが完全に問題ない場合、重複を追加しないようにする方法はありますか?

equals と hashcode の決定に使用されるどのフィールドも不変にする必要があると思いますか?

4

2 に答える 2

18

イコールとハッシュコードの決定に使用されるフィールドはどれも不変にする必要があると思いますか?

それは正しい。

Setより正確には、質問のコードは契約の次の部分に違反しています。

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

契約に違反すると、すべての賭けが無効になります。

于 2012-05-30T10:55:08.860 に答える
0

理解する例:

import java.util.*;

public class Vector1{

  public static void main(String args[]){


    Set v=new HashSet();
    Student st=new Student("12","naushad");
    Student st1=new Student("12","naushad");
    v.add(st1);
    v.add(st);
    System.out.println(st.hashCode());
    st.sname="shouzia";
    System.out.println(st.hashCode());

    v.add(st);
    v.add(st);
    v.add("naushad");
    v.add("naushad");
    v.add("naushad");

    System.out.println(v);
    }

}

class Student{

    public String sid;
    public String sname;

    Student(String sid,String sname){
        this.sid=sid;
        this.sname=sname;
    }

    public String toString(){

        return sid+"\t"+sname;
    }

}

同じデータで 2 つのオブジェクトをインスタンス化しましたが、両方に異なるハッシュコードが含まれているため、Set に格納されるため、ここでは equals() メソッドを比較する必要はありません。

hashcode() メソッドが同じハッシュコードを返す場合、オブジェクト プロパティを使用して equals() メソッドをチェックし、オブジェクト プロパティに何らかの変更があるかどうかをチェックします。結果に応じて、そのオブジェクトをセットに保存するか、保存しない場合があります。

于 2014-09-08T14:07:31.913 に答える