Я использую TreeBidiMap
из библиотеки Apache Collections. Я хочу разобраться с ценностями, которые являются «двойными».
Мой метод состоит в том, чтобы получить Collection
значений, используя:
Collection coll = themap.values();
Что естественно работает нормально.
Основной вопрос: Теперь я хочу знать, как я могу преобразовать / привести (не уверен, что правильно) coll
в List
, чтобы его можно было отсортировать?
Затем я намереваюсь перебрать объект List
, который должен быть в порядке, и получить соответствующие ключи от TreeBidiMap
(themap
), используя themap.getKey (iterator.next ())
, где итератор будет быть над списком doubles
.
List list = new ArrayList(coll);
Collections.sort(list);
Как говорит Эрел Сигал Халеви ниже, если coll уже есть список, вы можете пропустить первый шаг. Но это будет зависеть от внутренних элементов TreeBidiMap.
List list;
if (coll instanceof List)
list = (List)coll;
else
list = new ArrayList(coll);
Нечто подобное должно работать, вызывая конструктор ArrayList, который принимает коллекцию:
List theList = new ArrayList(coll);
Я думаю, что ответ Пола Томблина может быть расточительным, если coll уже есть список, потому что он создаст новый список и скопирует все элементы. Если в коллате содержится много элементов, это может занять много времени.
Мое предложение:
List list;
if (coll instanceof List)
list = (List)coll;
else
list = new ArrayList(coll);
Collections.sort(list);
Collections.sort( new ArrayList( coll ) );
@Kunigami: Я думаю, что вы можете ошибаться насчет метода «newArrayList» Гуавы. Он не проверяет, является ли Iterable типом списка, и просто возвращает данный список как есть. Он всегда создает новый список:
@GwtCompatible(serializable = true)
public static <E> ArrayList<E> newArrayList(Iterable<? extends E> elements) {
checkNotNull(elements); // for GWT
// Let ArrayList's sizing logic work, if possible
return (elements instanceof Collection)
? new ArrayList<E>(Collections2.cast(elements))
: newArrayList(elements.iterator());
}
То, что вы запрашиваете, является довольно дорогостоящей операцией, убедитесь, что вам не нужно делать это часто (например, в цикле).
В противном случае вы можете создать собственную коллекцию. Я придумал тот, у которого под капотом находятся ваши «TreeBidiMap» и «TreeMultiset». Реализуйте только то, что вам нужно, и заботьтесь о целостности данных.
class MyCustomCollection implements Map<K, V> {
TreeBidiMap<K, V> map;
TreeMultiset<V> multiset;
public V put(K key, V value) {
removeValue(map.put(key, value));
multiset.add(value);
}
public boolean remove(K key) {
removeValue(map.remove(key));
}
/** removes value that was removed/replaced in map */
private removeValue(V value) {
if (value != null) {
multiset.remove(value);
}
}
public Set keySet() {
return map.keySet();
}
public Multiset values() {
return multiset;
}
// many more methods to be implemented, e.g. count, isEmpty etc.
}
Таким образом, у вас есть sorted Multiset
, возвращенный из values ()
. Однако, если вам нужен список (например,. вам нужен метод get (index), похожий на массив, вам придется изобрести что-то более сложное.