2

フォーラムでこの質問に答えようとしたところequals、クラスでメソッドをオーバーライドしたにもかかわらず、Employee重複した要素をTreeSet.

TreeSet.add(E)メソッドのJavadocは言う

指定された要素がまだ存在しない場合は、このセットに追加します。より正式には、(e==null ? e2==null : e.equals(e2)) となる要素 e2 がセットに含まれていない場合、指定された要素 e をこのセットに追加します。このセットにすでに要素が含まれている場合、呼び出しはセットを変更せずに false を返します。

これは基本的に、2 つの等しいオブジェクトが挿入されず、含まれているオブジェクトのメソッドTreeSetによってのみ等しいかどうかが決定されることを意味します。equals()

ただし、以下のコードは、Set等しいにもかかわらず に2 つの要素を追加しています。

public class Employee implements Comparable<Employee> {

    String employeeName;
    int employeeId;

    public Employee(String name, int id) {
        this.employeeName = name;
        this.employeeId = id;
    }

    public int compareTo(Employee emp) {
        //return this.employeeName.compareTo(emp.employeeName);
        return (this.employeeId - emp.employeeId);
    }

    @Override
    public String toString() {
        return ("Name is: " + employeeName + " Emp id is: " + employeeId);
    }

    @Override
    public boolean equals(Object emp) {
        if(emp instanceof Employee &&((Employee)emp).employeeName.equals(this.employeeName)){
            return true;
        }
        return false;
    }

    /**
     * @param args
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Set<Employee> set = new TreeSet<Employee>();
        Employee e1 = new Employee("A", 1);
        Employee e2 = new Employee("A", 2);
        System.out.println(e1.equals(e2));
        set.add(e1);
        set.add(e2);
        System.out.println(set);
    }

}

そして、ここに出力があります

true
[Name is: A Emp id is: 1, Name is: A Emp id is: 2]

TreeSet等しい場合でも複数の要素を許可するのはなぜですか?

今、私はこのようなcompareTo方法を変更しましたEmployee

public int compareTo(Employee emp) {
    return this.employeeName.compareTo(emp.employeeName);
}

そして、出力は

true
[Name is: A Emp id is: 1]

TreeSetオーバーライド後、どのように適切に動作しますcompareToか?

4

3 に答える 3

9

TreeSet の javadoc にも次のように書かれています。

インターフェースを正しく実装するためには、(明示的なコンパレーターが提供されているかどうかに関係なく) セットによって維持される順序付けがequals と一致している必要があることに注意してください。Set( equals との整合性の正確な定義については、Comparableorを参照してください。) これは、インターフェイスが操作に関して定義されているためです。ただし、インスタンスは(or ) メソッドを使用してすべての要素の比較を実行するため、2 つの要素はこれによって等しいと見なされます。方法は、セットの観点からは同等です。セットの動作は、その順序付けが equals と一致しない場合でも明確に定義されています。インターフェイスの一般的な契約に従わないだけです。ComparatorSetequalsTreeSetcompareTocompareSet

の javadoc が、実際には使用されていないadd()ことをより明確にしequals()、この警告を再表示またはリンクできることに同意します。

于 2013-07-12T07:16:41.753 に答える
0

Set実装ではMap、舞台裏で を使用してデータを管理し、その際にMapのキーを通じてオブジェクトの一意性を保証します。

私の知る限り、equalsオブジェクトが明示的に同じオブジェクトでない場合 (つまり、'==') にオブジェクトが追加されることを意味する明示的なテストは行われていません。

ドキュメントは誤解を招くと思いますが、それは正式な言語表現だと言っていると思います。あいまいなので間違っている可能性がありますが、基になるマップのキーによって一意性が保証されていると確信しています。参考までに: オブジェクトをキーとしてダミー値が渡されます。

于 2013-07-12T07:26:20.797 に答える