2012-01-25 14 views
2

私の問題は非常に基本的ですが、正しく解決する方法はありません。私はエンティティの名前に基づいてコンパレータを使用するTreeSetを持っています。しかし、私はその名前を変更することができます。 TreeSetの並べ替えを強制するにはどうしたらいいですか?変更可能な属性に基づくTreeSetコンパイラ

TreeSet<MyEntity> set = new TreeSet<MyEntity>(new BeanComparator("name")); 
// bar < foo < xander 
set.add(foo); 
set.add(bar); 
set.add(xander); 
// resulting tree:  _-foo-_ 
//     bar xander 
xander.setName("apple"); 

set.contains(xander); // -> false, since now neither 'foo' or 'bar' are equal to 'xander' 

私は呼び出すべきである、または私はすべてが間違っているこのことについてつもり一部set.relayout()方法はありますか?

答えて

2

エレメントの名前を変更するときにツリーセットへのリンクがある場合は、そのエレメントをセットから削除し、その名前を変更して戻してください。

public class MyEntity { 
    private final TreeSet<MyEntity> container; 

    ... 

    public void setName(final String name) { 
    container.remove(this); 
    this.name = name; 
    container.add(this); 
    } 
} 

しかし、このよう

あなたは、私は(MyEntityでプライベートフィールドとしてそれを持ってお勧め、とのsetNameを書き換えたい、名前の更新時にそのリンクを持っていない場合)アプローチは非常に醜いです。あなたはそれを避けるほうがいいでしょう。

+0

有する容器を通知するMyEntityするためのものであることがあり、最初は、エラー傾向があります。 –

2

+1なぜあなたの検索が機能していないかを調べる。キーを持つコレクション内でキーを変更可能にすることは、ほとんど常に間違っています。

set.relayoutメソッドはありません。たとえあったとしても、正しいことをするにはclient codeが必要になりますが、それは間違いを起こしやすいです。

要素を削除して元に戻す必要があります。これは、同じようにエラーが発生しやすくなります。 1つの選択肢は、MyEntityを観測可能にし、extend TreeSetを変更して、その要素が削除されて追加されることで応答を受け取るようにすることです。

まだ、後者のアプローチが優れているがあり、しかし並行性の問題であり、それを解決する1つの方法は、beforeChangeafterChange

関連する問題