2009-02-24 23 views
202

Tôi đang sử dụng TreeBidiMap từ thư viện Apache Collections. Tôi muốn sắp xếp điều này trên các giá trị là doubles.Làm cách nào để chuyển đổi Bộ sưu tập thành Danh sách?

phương pháp của tôi là để lấy một Collection trong những giá trị sử dụng:

Collection coll = themap.values(); 

Mà tự nhiên hoạt động tốt.

Câu hỏi chính: bây giờ tôi muốn biết làm thế nào tôi có thể chuyển đổi/diễn viên (không chắc chắn đó là chính xác) coll thành một List để nó có thể được sắp xếp?

sau đó tôi có ý định lặp qua các sắp xếp List đối tượng, mà phải ở trong trật tự và lấy chìa khóa thích hợp từ TreeBidiMap (themap) sử dụng themap.getKey(iterator.next()) nơi iterator sẽ kết thúc danh sách các doubles.

+4

Bạn có thể muốn tránh bước này bằng cách trực tiếp sử dụng một số loại SortedMap, vì vậy mục nằm trong trật tự tự nhiên trong những chìa khóa được sử dụng. Bản đồ TreeMap của Java thực hiện SortedMap. –

+0

'TreeBidiMap' là một' OrderedMap', thứ tự sẽ là ok. Yêu cầu sắp xếp trong câu hỏi là trên các giá trị, không phải trên các khóa. – Vlasec

Trả lời

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

Như collel đã nêu, bạn có thể bỏ qua bước một. Nhưng điều đó sẽ phụ thuộc vào nội bộ của TreeBidiMap.

List list; 
if (coll instanceof List) 
    list = (List)coll; 
else 
    list = new ArrayList(coll); 
+1

Chỉ cần lưu ý rằng có những tác dụng phụ khác nhau đối với hai cách tiếp cận: đúc bộ sưu tập vào danh sách và sau đó sắp xếp cũng sẽ sắp xếp bộ sưu tập gốc; tạo một bản sao sẽ không. – Barney

+0

Cách tiếp cận này làm giảm hiệu suất rất nhiều nếu được sử dụng nhiều lần. Xem câu trả lời của tôi cho một giải pháp hoạt động liên tục, nó liên quan đến một bộ sưu tập tùy chỉnh. – Vlasec

58

Something như thế này nên làm việc, gọi ArrayList constructor mà phải mất một Bộ sưu tập:

List theList = new ArrayList(coll); 
7
Collections.sort(new ArrayList(coll)); 
+0

Thiếu tham chiếu để truy cập ArrayList? –

+0

@Zach: mmhh điểm tốt. Tôi biết có một lý do để tôi đánh dấu nó là CW. BTW của Paul ans là một. Tôi không biết tại sao anh ta chỉ có uv của tôi. – OscarRyz

29

Tôi nghĩ rằng câu trả lời Paul Tomblin có thể là lãng phí trong trường hợp coll là đã là một danh sách, bởi vì nó sẽ tạo danh sách mới và sao chép tất cả các phần tử. Nếu coll chứa nhiều elemeents, điều này có thể mất một thời gian dài.

Đề nghị của tôi là:

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

@Kunigami: Tôi nghĩ rằng bạn có thể bị nhầm lẫn về phương pháp newArrayList ổi của. Nó không kiểm tra xem Iterable có phải là một kiểu List hay không và đơn giản là trả về danh sách đã cho. Nó luôn tạo ra một danh sách mới:

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

Làm thế nào điều này không được bỏ phiếu nhiều hơn? Câu trả lời của Kunigami là không chính xác (theo như nó giả định về việc thực hiện cơ bản). – GreenieMeanie

-1

Dưới đây là một giải pháp tối ưu phụ như một lớp lót:

Collections.list(Collections.enumeration(coll)); 
1

gì bạn yêu cầu là khá một hoạt động costy, chắc chắn rằng bạn don' t cần phải làm điều đó thường xuyên (ví dụ như trong một chu kỳ).

Nếu không, bạn có thể tạo bộ sưu tập tùy chỉnh. Tôi đã đưa ra một số có TreeBidiMapTreeMultiset dưới mui xe. Chỉ thực hiện những gì bạn cần và quan tâm đến tính toàn vẹn của dữ liệu.

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. 
} 

Bằng cách này, bạn có một sắp xếpMultiset trở về từ values(). Tuy nhiên, nếu bạn cần danh sách đó (ví dụ: bạn cần phương thức giống như phương pháp get(index) theo mảng), bạn phải phát minh ra điều gì đó phức tạp hơn.

4

Tôi tin rằng bạn có thể viết nó như vậy:

coll.stream().collect(Collectors.toList()) 
+0

Cách tốt hơn để khám phá – Stackee007

Các vấn đề liên quan