2012-11-19 10 views
11

私はその構造体のSetを持っています。私は重複を持っていませんが、私が電話すると: set.add(要素) - >と私は古いものを置き換えることを望んでいる正確な要素が既にあります。HashSet Javaメンバの置き換え

+0

コードスニペットと質問との関係を理解することができません。あなたのコードのどこにそれが設定されていますか?また、あなたのオブジェクトがまったく同じであれば、なぜ置き換えたいのですか? –

+0

@ YogendraSingh - OPは、古い「WordInfo」を古いものと「等しい」(同じ)オブジェクトではない新しいものに置き換えたいと考えています。 ( 'equals()'テストは 'wystapienia'の値を無視します)。 –

+0

@TedHopp:ありがとうございますが、' this this.plik.equals((WordInfo)obj).plik)を返します。 trueを返す、いいえ?? –

答えて

22

は、それぞれの前に削除を実行してください追加します。

someSet.remove(myObject); 
someSet.add(myObject); 

を削除するにはmyObjectというに等しい任意のオブジェクトを削除します。また、追加の結果を確認することができます。より効率的である

if(!someSet.add(myObject)) { 
    someSet.remove(myObject); 
    someSet.add(myObject); 
} 

は、あなたが衝突を持っているどのくらいの頻度によって異なります。それらがまれである場合、第2の形式は通常1回の操作しか行いませんが、衝突がある場合は3回の操作しか行いません。最初の形式は常に2つです。

+0

これは、スレッド「main」の「java.util。'Iterator'と一緒に使用するとConcurrentModificationException'が発生します。 – ThreaT

+0

@ThreaTこれは、この問題とは別の問題です。これは、呼び出すことができる状況での' add'の動作の変更に関するものです。私はあなたに役立つ既存の質問を見つけることができない限り、あなたがコメントに入れることができるより多くの背景と、新しい質問としてそれを求めることをお勧めします。 –

-1

JDK内のHashSetコードを確認してください。 要素が追加されて複製されると、古い値が置き換えられます。 フォークは、新しい要素が破棄されたと思っています。間違っています。 あなたのケースでは、追加のコードは必要ありません。

はI JDKのコードを再読み込み、そして私が作った間違いを認める---------------------

を更新しました。

putが作成されると、VALUEはHashMapのKEYではなく置き換えられます。

なぜ私はHashmapについて話していますか?だから、PRESENT値は、コードのこの部分に示すように、新しいものと交換され

public boolean add(E e) { 
    return map.put(e, PRESENT)==null; 
} 

:あなたはHashSetコードを見れば、あなたはわかりますので

 public V put(K key, V value) { 
     if (key == null) 
      return putForNullKey(value); 
     int hash = hash(key); 
     int i = indexFor(hash, table.length); 
     for (Entry<K,V> e = table[i]; e != null; e = e.next) { 
      Object k; 
      if (e.hash == hash && ((k = e.key) == key || key.equals(k))) { 
       V oldValue = e.value; 
       e.value = value; 
       e.recordAccess(this); 
       return oldValue; 
      } 
     } 

     modCount++; 
     addEntry(hash, key, value, i); 
     return null; 
    } 

しかし、私は同意し、 keyは置換されず、keyHashSet'sの値を表しているため、この値は「変更されていない」と言われています。次のように

+1

これは、内部実装の詳細であり、***に依存してはいけません。 – Perception

+0

しかし、古いものは残っています。/ – Yoda

+0

置き換えが発生した場合、HashSetは「Set for contract for add」に従っていません。呼び出しによってセットが変更されずにfalseが返されます。 –

0

は(equalshashCode 1つのフィールドに依存しますが、他のフィールドの値が異なることができれば、これが唯一の意味を行います)何かを試してみてください:

if(!set.add(obj)) { 
    //set already contains the element (not the same object though) 
    set.remove(obj); //remove the one in the set 
    set.add(obj); //add the new one 
} 

Set.addメソッドのドキュメントをチェックアウト

このセットにすでに要素が含まれている場合、呼び出しはセットを変更しないままにし、falseを返します。

+0

-1これは動作しません。あなたはいつも 'set()'が返すものに関係なく、追加したいと思っています – Bohemian

+0

私は質問を誤読しました。 –

+0

ok no -1ですが、あなたの答えはPatriciaのものとまったく同じです。彼女は最初に「正しく」答えるようになりました。 – Bohemian

3

セットに既に追加しようとしている要素がequals()の場合、新しい要素は追加されず、既存の要素が置き換えられません。単に最初のセットから削除し、新たな要素が追加されていることを保証するために:私はセットを持っていた問題に取り組んでいた

set.remove(aWordInfo); 
set.add(aWordInfo); 
+0

ほんの少し前にそれをしました:)働いた – Yoda

0

その後、私は交換してください/別のオブジェクトとオブジェクトの一部を上書きしたいですセット。

私がやったことは、新しいセットを作成してオーバーライドを最初に入れてから現在のオブジェクトを2番目に追加することでした。これは、新しいオブジェクトを追加するときにセットが既存のオブジェクトを置き換えないために機能します。

お持ちの場合:

Set<WordInfo> currentInfo; 
Set<WorldInfo> overrides; 

の代わりに:

私がやった
for each override, replace the object in current info 

Set<WordInfo> updated = new HashSet<>(); 
updated.addAll(overrides); 
updated.addAll(currentInfo); 
関連する問題