2

私は以下のようなクラスを持っています(Bean):

class KeysHolder {
   Long kitId;
   String packId;
   String boxId;

   // getters and setters
    .......
   // @Override equals and hashCode
}

上記のオブジェクトを含むセットがあります

 Set<KeysHolder> keys;

オブジェクトをセットに追加し続けると、各要素の値に基づいて重複が自動的に削除されますか? (内部で Overridden equals および hashCode メソッドを使用していることを理解しています)。

最終的なセットには、各フィールドが等しいことに基づいて重複が含まれていてはなりません。

  obja.kitId = objb.kitId
  objb.packid = objb.packId
  obja.boxId = objb.boxId

ありがとう!

4

5 に答える 5

7

オブジェクトをセットに追加し続けると、各要素の値に基づいて重複が自動的に削除されますか。

実装によって重複が見つかった場合、要素Setはまったく挿入されません。

HashSet#add(E e)の Javadoc から:

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

于 2013-06-20T19:35:16.443 に答える
2

はい、どのSet実装でも重複は許可されません。

ただし、注意事項があります。およびその他のハッシュベースのコレクションの場合、Set挿入しようとするオブジェクトがそれらのオブジェクトとメソッドを正しくオーバーライドすることを確認する必要がありequals()ますhashCode()

正しいとは、 は意味のある同等の 2 つのオブジェクトをequals()返す必要があり、 は入力セット内のオブジェクトの範囲に対して可能な限り異なる値を返そうとすることを意味します。truehashCode()

不適切なequals()実装を行うと、プログラムが破損する可能性が高くなります。非効率的なhashCode()実装は、Setのパフォーマンスを低下させます。つまりadd()contains()などの操作は、実装と同じくらい遅くなります。

于 2013-06-20T19:45:32.823 に答える
2

短い答えはイエスです。どのセットもそれ自体で重複除外を実行します。しかし、それは契約を尊重する場合にのみ保証されます。Setコントラクトは実装ごとに少し異なります。

についてはHashSet、お気づきのように、実装する必要がhashCode()ありequals()ます。しかし、それだけでは十分ではありません。変更可能なインスタンスを a に保持、/の結果にHashSet影響するプロパティを変更すると、依然として奇妙な状況に陥ります。hashCode()equals()

TreeSet一方、 では、 または メソッドが と一致していることを確認する必要がComparable.compareTo()ありComparator.compare()ますequals()

したがって、のドキュメントSetと、ニーズに合った実際の実装のドキュメントを読み、契約に固執するようにしてください。

于 2013-06-20T19:49:03.690 に答える
1

HashSet は内部的に HashMap を使用します。このマップはキーをセットに追加する値として維持され、値は Object クラスのインスタンスです ( final private static final Object PRESENT = new Object(); )。ここで、同じオブジェクトをこのセットに追加すると、値を更新するだけで、同じキーで map.put を実行したときに map が行うのと同じ操作になります。

ただし、更新される値はPRESENTのままです。したがって、ある意味では、セットは同じ値を追加しないと言えます。ただし、実際には、このセットを実装するために内部で使用されるマップは、*同じキー* と同じ値 (PRESENT) で自身を更新しています。

于 2013-06-20T19:48:17.757 に答える