2012-01-25 3 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

요소 이름을 변경할 때 TreeSet에 대한 링크가있는 경우 해당 요소를 집합에서 제거하고 이름을 변경 한 다음 다시 삽입하면됩니다. 당신이 이름을 갱신시 링크가없는 경우

, 그때 MyEntity에서 개인 필드로 그것을 가지고하는 것이 좋습니다, 그리고

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

    ... 

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

그러나,이 같은에서는 setName()를 다시 것 접근 방식은 매우 못생긴다. 당신은 그것을 피하는 것이 좋습니다.

+0

아니, 후자의 방법이 더 afterChange과 용기를 통지하는 것이이 해결 동시성 문제가있을 수 있습니다. –

2

+1 왜 검색이 작동하지 않는지 알아보십시오. 키가있는 콜렉션에서 키를 변경할 수있게하는 것은 거의 항상 잘못된 것입니다.

set.relayout 메서드가 없습니다. 있을지라도, 당신은 client code에 옳은 일을 할 필요가 있으며, 이것은 매우 오류를 일으키는 경향이 있습니다.

그래서 요소를 제거하고 다시 추가해야합니다. 또한 오류가 발생하기 쉽습니다. 한 가지 대안은 MyEntity을 관찰 가능하게 만들고 extend TreeSet을 변경하여 요소를 제거하고 추가하여 변경 사항에 대한 알림을 받도록하는 것입니다.

여전히 첫 번째는 오류 경향이있다,하지만 한 가지 방법이 MyEntitybeforeChange