[英]How to convert a Collection<Collection<Double>> to a List<List<Double>>?
[英]How to convert a Collection to List?
我正在使用TreeBidiMap
Collections庫中的 TreeBidiMap。 我想對doubles
的值進行排序。
我的方法是使用以下方法檢索值的Collection
:
Collection coll = themap.values();
這自然可以正常工作。
主要問題:我現在想知道如何將coll
轉換/轉換(不確定哪個是正確的)為List
以便對其進行排序?
然后我打算遍歷排序List
object,它應該是有序的,並使用themap.getKey(iterator.next())
從TreeBidiMap
( themap
) 獲取適當的鍵,其中迭代器將在doubles
列表上。
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);
像這樣的東西應該可以工作,調用帶有 Collection 的ArrayList 構造函數:
List theList = new ArrayList(coll);
如果 coll 已經是一個列表,我認為 Paul Tomblin 的答案可能是浪費的,因為它將創建一個新列表並復制所有元素。 如果 coll 包含許多元素,這可能需要很長時間。
我的建議是:
List list;
if (coll instanceof List)
list = (List)coll;
else
list = new ArrayList(coll);
Collections.sort(list);
我相信你可以這樣寫:
coll.stream().collect(Collectors.toList())
Collections.sort( new ArrayList( coll ) );
Java 10 引入了List#copyOf
,它在保留順序的同時返回不可修改的 List :
List<Integer> list = List.copyOf(coll);
@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());
}
您要求的操作成本很高,請確保您不需要經常進行(例如在一個周期中)。
如果您需要它保持排序並且經常更新它,您可以創建一個自定義集合。 例如,我想出了一個在引擎蓋下有你的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<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
}
這樣,您就有了一個從values()
返回的排序Multiset
。 但是,如果您需要它是一個列表(例如,您需要類似數組的get(index)
方法),則需要更復雜的東西。
為簡潔起見,我只返回不可修改的 collections。 @Lino 提到的是正確的,並且按原樣修改keySet
或values
集合會使其不一致。 我不知道使values
可變的任何一致方法,但是如果keySet
使用上面的MyCustomCollection
class 中的remove
方法,它可以支持remove
。
使用流:
someCollection.stream().collect(Collectors.toList())
Java 8 起...
您可以使用Streams和Collectors.toCollection() 將 Collection 轉換為任何集合(即 List、Set 和 Queue) 。
考慮以下示例 map
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)
);
Output:[7351.03、2348.26、1234.86、8956.31、1015.45]
排序為 ArrayList(升序)
List<Double> arrayListSortedAsc = map.values()
.stream()
.sorted()
.collect(
Collectors.toCollection(ArrayList::new)
);
Output:[1015.45、1234.86、2348.26、7351.03、8956.31]
排序為 ArrayList(降序)
List<Double> arrayListSortedDesc = map.values()
.stream()
.sorted(
(a, b) -> b.compareTo(a)
)
.collect(
Collectors.toCollection(ArrayList::new)
);
Output:[8956.31、7351.03、2348.26、1234.86、1015.45]
到鏈表
List<Double> linkedList = map.values()
.stream()
.collect(
Collectors.toCollection(LinkedList::new)
);
Output:[7351.03、2348.26、1234.86、8956.31、1015.45]
到哈希集
Set<Double> hashSet = map.values()
.stream()
.collect(
Collectors.toCollection(HashSet::new)
);
Output:[2348.26、8956.31、1015.45、1234.86、7351.03]
到優先隊列
PriorityQueue<Double> priorityQueue = map.values()
.stream()
.collect(
Collectors.toCollection(PriorityQueue::new)
);
Output:[1015.45、1234.86、2348.26、8956.31、7351.03]
參考
這是作為單線的次優解決方案:
Collections.list(Collections.enumeration(coll));
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.