並べ替えセットを繰り返して内部のアイテムを変更する方法
質問
リストがあるとしましょう。 forループでリストのアイテムを変更するのに問題はありません。
for (int i = 0; i < list.size(); i++) { list.get(i).setId(i); }
しかし、私はリストの代わりにソートセットを持っています。どうすれば同じことをすることができますか?ありがとうございました
解決
初めに、 Set
その要素が不変であると仮定します(実際、可変要素 それは 許可されていますが、彼らは非常に具体的な契約を遵守する必要があります。
これは、一般に、リストを使用しているように、設定された要素を内装することができないことを意味します。
2つの基本操作a Set
サポートは、要素の追加と除去です。修正は、古い要素の除去と新しいものの追加と考えることができます。
- 繰り返して、
Iterator.remove()
; - 追加を別の容器に蓄積して呼び出すことができます
Set.addAll()
最後に。
他のヒント
SETのキーを変更することはできません。セットの再順序付けを引き起こすためです。したがって、反復がさらに実行される方法は未定義の動作になります。
iterator.remove()を使用して要素を削除できます。ただし、要素を追加することはできません。通常、より良い解決策は、新しいコレクションにそれらを蓄積し、反復後に追加することです。
Set mySet = ...;
ArrayList newElems = new ArrayList();
for(final Iterator it = mySet.iterator(); it.hasNext(); )
{
Object elem = it.next();
if(...)
newElems.add(...);
else if(...)
it.remove();
...
}
mySet.addAll(newElems);
Java 1.6以来、aを使用できます NavigableSet
.
を使用する必要があります Iterator
または、拡張されたfor-loop構文(これは、実装するクラスに依存します Iterable
インターフェース)、に関係なく Collection
あなたが使用しています。これは、コレクションを通過するために使用されるメカニズムを抽象化し、反復ルーチンに影響を与えることなく新しい実装を置き換えることができます。
例えば:
Set<Foo> set = ...
// Enhanced for-loop syntax
for (Foo foo : set) {
// ...
}
// Iterator approach
Iterator it = set.iterator();
while (it.hasNext()) {
Foo foo = it.next();
}
編集
Kanは、アイテムのキーを変更することについて良い点を指摘しています。あなたのクラスのものを仮定して equals()
と hashCode()
メソッドは、「ID」属性(変更している)のみに基づいています。最も安全なアプローチは、これらを明示的に削除することです Set
繰り返して「出力」に追加すると Set
;例えば
SortedSet<Foo> input = ...
SortedSet<Foo> output = new TreeSet<Foo>();
Iterator<Foo> it = input.iterator();
while (it.hasNext()) {
Foo foo = it.next();
it.remove(); // Remove from input set before updating ID.
foo.setId(1);
output.add(foo); // Add to output set.
}
それをしてはいけない。しかし、あなたは試してみるかもしれません、多分あなたは成功するでしょう、多分あなたは得るでしょう ConcurrentModificationException
. 。反復中に要素を変更すると予期しない結果が得られる可能性があることを覚えておくことが非常に重要です。代わりに、いくつかのコレクションでその要素を収集する必要があります。反復後、それらを1つずつ変更します。
これは、場合にのみ機能します id
等しい、または並べ替えられたセットに使用したコンセレーターには使用されていません。
int counter = 0;
for(ElementFoo e : set) {
e.setId(counter);
couter++;
}