Java Map Value Comparator, сортировка при вставке
Я хотел бы вставить элементы в HashMap, TreeMap или SortedMap (вы можете предложить некоторые другие API), используя значение Comparator.
Я прочитал много постов, включая этот, большинство постов предлагают повторно вставить HashMap в SortedMap со значением Comparator после того, как все элементы были вставлены.
Мне не интересно снова вставлять все значения. Нет ли опции или структуры данных, аналогичной Map, которая поддерживает активацию значения Comparator после каждой вставки?
Если есть повторяющаяся проблема, я был бы признателен за ссылку (я провел поиск, хотя, возможно, пропустил некоторые)
Опять же, я заинтересован в добавлении значения к некоторой упорядоченной карте, так что все элементы будут упорядочены по значению, а не по ключу, после каждой отдельной вставки.
Значение в записи Map на самом деле является сложным объектом с некоторыми получателями, и я хочу отсортировать только по определенному получателю для объекта значения.
4 ответа
У меня есть хоть какой-то обходной путь, он не идеален и будет использовать больше памяти, но он довольно прост.
Я могу расширить ключ Map, чтобы он также содержал значение, возвращаемое получателем объекта Value. Затем я расширю ключ Comparator для сортировки по правильному кортежу ключа.
ОБНОВИТЬ
Работал как шарм с очень хорошим исполнением.
Я думаю, что вам нужно org.apache.commons.collections.bidimap.TreeBidiMap
Красно-черная реализация BidiMap на основе дерева, в которой все добавленные объекты реализуют интерфейс Comparable.
Этот класс гарантирует, что карта будет в порядке возрастания ключа и в порядке возрастания значения, отсортированного в соответствии с естественным порядком для классов ключа и значения.
Карты все о переходе от ключа к значению. В Guava есть концепция двунаправленных отображений, но вам не нужно переходить от значения к ключу, а нужно разобраться в отсортированной итерации значений. Что я рекомендую, так это пользовательский контейнер, в котором будут размещаться HashMap и Priority Queue.
Таким образом, расширьте интерфейсы Map, Collection и Iterable и добавьте их в HashMap и Priority Queue. Когда вы выполняете итерацию, выполняйте итерацию по очереди, когда вы выполняете поиск / переход на карту.
Я искал что-то подобное и не мог использовать TreeBidiMap
потому что для реализации интерфейса Comparable требуются ключи карты.
Так что я написал свой минималистичный ValueTreeMap
:
import java.util.HashMap;
import java.util.Iterator;
import java.util.TreeSet;
public class ValueTreeMap<K, V extends Comparable<V>> implements Iterable<V> {
private TreeSet<V> tree = new TreeSet<V>();
private HashMap<K, V> map = new HashMap<K, V>();
public void put(K key, V value){
V oldValue = map.get(key);
if(oldValue != null){
tree.remove(oldValue);
}
tree.add(value);
map.put(key, value);
}
public V get(K key){
return map.get(key);
}
@Override
public Iterator<V> iterator() {
return tree.iterator();
}
}