Как правило, лучше вручную сохранять отсортированные значения Set
/ Map
непрерывно согласованными (см. Стратегию, упомянутую @aioobe).
Однако иногда это не вариант. В этих случаях мы можем попробовать это:
if (treeSet.contains(item)) {
treeSet.remove(item);
treeSet.add(item);
}
или с картой:
if (treeMap.containsKey(key)) {
Value value = treeMap.get(key);
treeMap.remove(key);
treeMap.put(key, value);
}
Но это не будет работать правильно, потому что даже containsKey
может привести к неверному результату.
Так что мы можем сделать с грязной картой? Как мы можем обновить один ключ без необходимости перестраивать всю карту? Вот вспомогательный класс для решения этой проблемы (может быть легко преобразован в наборы):
public class MapUtil {
/**
* Rearranges a mutable key in a (potentially sorted) map
*
* @param map
* @param key
*/
public static <K, V> void refreshItem(Map<K, V> map, K key) {
SearchResult<K, V> result = MapUtil.searchMutableKey(map, key);
if (result.found) {
result.iterator.remove();
map.put(key, result.value);
}
}
/**
* Searches a mutable key in a (potentially sorted) map
*
* Warning: currently this method uses equals() to check equality.
* The returned object contains three fields:
* - `found`: true iff the key found
* - `value`: the value under the key or null if `key` not found
* - `iterator`: an iterator pointed to the key or null if `key` not found
*
* @param map
* @param key
* @return
*/
public static <K, V> SearchResult<K, V> searchMutableKey(Map<K, V> map, K key) {
Iterator<Map.Entry<K, V>> entryIterator = map.entrySet().iterator();
while (entryIterator.hasNext()) {
Map.Entry<K, V> entry = entryIterator.next();
if (key.equals(entry.getKey())) {
return new SearchResult<K, V>(true, entry.getValue(), entryIterator);
}
}
return new SearchResult<K, V>(false, null, null);
}
public static class SearchResult<K, V> {
final public boolean found;
final public V value;
final public Iterator<Map.Entry<K, V>> iterator;
public SearchResult(boolean found, V value, Iterator<Map.Entry<K, V>> iterator) {
this.found = found;
this.value = value;
this.iterator = iterator;
}
}
}