328

我正在使用TreeBidiMapApache Collections库。我想对它的值进行排序doubles

我的方法是使用以下方法检索一个Collection值:

Collection coll = themap.values();

这自然可以正常工作。

主要问题:我现在想知道如何将(不确定哪个是正确的)转换/转换coll为 aList以便对其进行排序?

然后我打算迭代排序的List对象,它应该是有序的,并使用迭代器在列表中的位置从TreeBidiMap( themap) 中获取适当的键。themap.getKey(iterator.next())doubles

4

11 回答 11

503
List list = new ArrayList(coll);
Collections.sort(list);

正如 Erel Segal Halevi 下面所说,如果 coll 已经是一个列表,您可以跳过第一步。但这将取决于 TreeBidiMap 的内部结构。

List list;
if (coll instanceof List)
  list = (List)coll;
else
  list = new ArrayList(coll);
于 2009-02-24T02:02:14.457 回答
106

像这样的东西应该可以工作,调用带有 Collection的ArrayList 构造函数:

List theList = new ArrayList(coll);
于 2009-02-24T02:03:09.960 回答
33

如果 coll 已经是一个列表,我认为 Paul Tomblin 的答案可能是浪费的,因为它将创建一个新列表并复制所有元素。如果 coll 包含许多元素,这可能需要很长时间。

我的建议是:

List list;
if (coll instanceof List)
  list = (List)coll;
else
  list = new ArrayList(coll);
Collections.sort(list);
于 2011-07-24T10:25:41.633 回答
27

我相信你可以这样写:

coll.stream().collect(Collectors.toList())
于 2017-08-24T14:20:02.760 回答
12

Java 10 引入了在保留顺序的同时List#copyOf返回不可修改的列表:

List<Integer> list = List.copyOf(coll);
于 2020-06-21T14:08:02.100 回答
10
Collections.sort( new ArrayList( coll ) );
于 2009-02-24T02:06:40.327 回答
4

@Kunigami:我认为您可能对 Guava 的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());
}
于 2014-01-08T21:39:10.523 回答
1

您要求的操作成本很高,请确保您不需要经常进行(例如在一个周期中)。

如果您需要它保持排序并且经常更新它,您可以创建一个自定义集合。例如,我想出了一个有你的TreeBidiMapTreeMultiset引擎盖下的。仅实施您需要的并关心数据完整性。

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<K> keySet() {
        return Collections.unmodifiableSet(map.keySet());
    }
    public Collection<V> values() {
        return Collections.unmodifiableCollection(multiset);
    }
    // many more methods to be implemented, e.g. count, isEmpty etc.
    // but these are fairly simple
}

这样,您就有一个 Multisetvalues(). 但是,如果您需要它是一个列表(例如,您需要类似数组的get(index)方法),您就需要一些更复杂的东西。

为简洁起见,我只返回不可修改的集合。@Lino 提到的是正确的,并且按原样修改keySetorvalues集合会使其不一致。我不知道任何一致的方法来使values可变,但如果它使用上面类中的方法,则keySet可以支持。removeremoveMyCustomCollection

于 2015-05-28T15:43:24.147 回答
0

使用流:

someCollection.stream().collect(Collectors.toList())
于 2020-09-16T21:23:47.440 回答
0

Java 8 以后...

您可以使用StreamsCollectors.toCollection()将 Collection 转换为任何集合(即 List、Set 和 Queue ) 。

考虑以下示例地图

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

到数组列表

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]

到链表

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

输出:[7351.03、2348.26、1234.86、8956.31、1015.45]

到哈希集

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

输出:[2348.26、8956.31、1015.45、1234.86、7351.03]

到优先队列

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

于 2021-05-07T20:19:15.973 回答
-4

这是作为单线的次优解决方案:

Collections.list(Collections.enumeration(coll));
于 2014-07-29T14:57:14.400 回答