Как преобразовать коллекцию в список?

Я использую TreeBidiMap из библиотеки Apache Collections. Я хочу отсортировать это по значениям, которые doubles,

Мой метод состоит в том, чтобы получить Collection из значений, использующих:

Collection coll = themap.values();

Что, естественно, отлично работает.

Основной вопрос: теперь я хочу знать, как я могу конвертировать / кастовать (не уверен, что это правильно) coll в List так это можно отсортировать?

Затем я намерен перебрать отсортированный List объект, который должен быть в порядке и получить соответствующие ключи от TreeBidiMap (themap) с помощью themap.getKey(iterator.next()) где итератор будет над списком doubles,

11 ответов

Решение
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.stream().collect(Collectors.toList())

Я думаю, что ответ Пола Томблина может быть расточительным, если coll уже является списком, потому что он создаст новый список и скопирует все элементы. Если в coll содержится много элементов, это может занять много времени.

Мое предложение:

List list;
if (coll instanceof List)
  list = (List)coll;
else
  list = new ArrayList(coll);
Collections.sort(list);

Представлена ​​Java 10 List#copyOfкоторый возвращает неизменяемый список при сохранении порядка:

List<Integer> list = List.copyOf(coll);
Collections.sort( new ArrayList( coll ) );

Java 8 и новее ...

Вы можете преобразовать Collection в любую коллекцию (например, List, Set и Queue) с помощью Streams и Collectors.toCollection () .

Рассмотрим следующий пример карты

      Map<Integer, Double> map = Map.of(
    1, 1015.45,
    2, 8956.31,
    3, 1234.86,
    4, 2348.26,
    5, 7351.03
);

в ArrayList

      List<Double> arrayList = map.values()
                            .stream()
                            .collect(
                                Collectors.toCollection(ArrayList::new)
                            );

Выход: [7351.03, 2348.26, 1234.86, 8956.31, 1015.45]

в Sorted ArrayList (в порядке возрастания)

      List<Double> arrayListSortedAsc = map.values()
                                        .stream()
                                        .sorted()
                                        .collect(
                                            Collectors.toCollection(ArrayList::new)
                                        );

Выход: [1015.45, 1234.86, 2348.26, 7351.03, 8956.31]

в Sorted ArrayList (в порядке убывания)

      List<Double> arrayListSortedDesc = map.values()
                                        .stream()
                                        .sorted(
                                            (a, b) -> b.compareTo(a)
                                        )
                                        .collect(
                                            Collectors.toCollection(ArrayList::new)
                                        );

Выход: [8956.31, 7351.03, 2348.26, 1234.86, 1015.45]

в LinkedList

      List<Double> linkedList = map.values()
                                .stream()
                                .collect(
                                    Collectors.toCollection(LinkedList::new)
                                );

Выход: [7351.03, 2348.26, 1234.86, 8956.31, 1015.45]

в HashSet

      Set<Double> hashSet = map.values()
                            .stream()
                            .collect(
                                Collectors.toCollection(HashSet::new)
                            );

Выход: [2348.26, 8956.31, 1015.45, 1234.86, 7351.03]

в PriorityQueue

      PriorityQueue<Double> priorityQueue = map.values()
                                            .stream()
                                            .collect(
                                                Collectors.toCollection(PriorityQueue::new)
                                            );

Выход: [1015.45, 1234.86, 2348.26, 8956.31, 7351.03]

Справка

Java - пакет java.util.stream

Java - пакет java.util

@Kunigami: я думаю, что вы можете ошибаться насчет Гуавы newArrayList метод. Он не проверяет, является ли Iterable типом List, и просто возвращает заданный List как есть. Он всегда создает новый список:

@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());
}

Используйте потоки:

someCollection.stream().collect(Collectors.toList())

То, что вы запрашиваете, является довольно дорогостоящей операцией, убедитесь, что вам не нужно делать это часто (например, в цикле).

В противном случае вы можете создать собственную коллекцию. Я придумал тот, который имеет ваш 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.
}

Таким образом, у вас есть отсортированный Multiset вернулся из values(), Тем не менее, если вам нужно, чтобы это был список (например, вам нужен массив, как get(index) метод), вам придется изобрести что-то более сложное.

Вот неоптимальное решение в виде однострочника:

Collections.list(Collections.enumeration(coll));
Другие вопросы по тегам