2010-10-13 41 views
12

Giải pháp "tốt" (và tại sao?) Là gì để lấy số List từ số Set và được sắp xếp theo một số Comparator nhất định?Cách lấy Danh sách từ Bộ và So sánh

+0

Câu hỏi này không rõ ràng. Ví dụ, tôi có thể lấy một List từ một Set và một Comparator bằng cách bỏ qua Comparator. Đó là một giải pháp "tốt" ... theo nghĩa là nó nhanh hơn các giải pháp sử dụng Comparator. –

+0

@Bước khi tôi cập nhật câu hỏi của tôi –

+1

Bạn có chắc là bạn cần một Danh sách không? Có thể một SortedSet sẽ làm. –

Trả lời

11
Set<Object> set = new HashSet<Object>(); 

// add stuff 

List<Object> list = new ArrayList<Object>(set); 
Collections.sort(list, new MyComparator()); 
+0

vừa thêm COllections.sort() sau đó. –

+0

Câu trả lời sai, điều này sẽ không hoạt động vì hàm tạo của ArrayList không sắp xếp bất kỳ thứ gì, thậm chí bạn chưa sử dụng Trình so sánh của mình, vậy làm thế nào nó sẽ được sắp xếp? Sử dụng hoặc Collections.sort() hoặc TreeSet, như trong các câu trả lời khác. – iirekm

+0

Đã sửa câu trả lời để bao gồm cuộc gọi sắp xếp. –

6

Chỉ cần xây dựng nó. ArrayListconstructor taking another Collection.

Set<Foo> set = new TreeSet<Foo>(new FooComparator<Foo>()); 
// Fill it. 

List<Foo> list = new ArrayList<Foo>(set); 
// Here's your list with items in the same order as the original set. 
0

Đây là cách bạn có được một List khi bạn có một Set:

List list = new ArrayList(set); 

Không chắc chắn những gì bạn mong đợi để làm với các Comparator. Nếu Set được sắp xếp, danh sách sẽ chứa các phần tử theo thứ tự được sắp xếp.

+1

Rõ ràng anh ta hy vọng sẽ sử dụng bộ so sánh để có được một danh sách được sắp xếp, ngụ ý rằng tập hợp được phân loại. Bạn sẽ sử dụng một bộ so sánh nào khác? Vì vậy, anh ta nên hoặc là đi qua một tập hợp được sắp xếp hoặc sắp xếp danh sách sau khi điền nó. –

+0

@Christoffer Hammarström - hoặc sắp xếp nó khi/bằng cách chèn từng phần tử: sắp xếp chèn. – Ishtar

+0

@ Ishtar: Đó là những gì sẽ xảy ra nếu bạn đi qua một tập hợp được sắp xếp, gợi ý đầu tiên của tôi. –

2

Hoặc:

Set<X> sortedSet = new TreeSet<X>(comparator); ... 
List<X> list = new ArrayList<X>(sortedSet); 

hay:

Set<X> unsortedSet = new HashSet<X>(); ... 
List<X> list = new ArrayList<X>(unsortedSet); 
Collections.sort(list, comparator); 
1

Giả sử rằng bạn bắt đầu với một bộ không được phân loại hoặc một tập được sắp xếp trên một trật tự khác nhau, sau đây có lẽ là hiệu quả nhất giả định rằng bạn yêu cầu Danh sách có thể sửa đổi.

Set<T> unsortedSet = ... 
List<T> list = new ArrayList<T>(unsortedSet); 
Collections.sort(list, comparator); 

Nếu một Danh sách unmodifiable là chấp nhận được, thì sau đây là nhanh hơn một chút:

Set<T> unsortedSet = ... 
T[] array = new T[unsortedSet.size()]; 
unsortedSet.toArray(array); 
Arrays.sort(array, comparator); 
List<T> list = Arrays.asList(array); 

Trong phiên bản đầu tiên, Collections.sort(...) sao chép nội dung danh sách vào một mảng, sắp xếp các mảng, và sao chép các yếu tố được sắp xếp trở lại danh sách. Phiên bản thứ hai là nhanh hơn bởi vì nó không cần phải sao chép các yếu tố được sắp xếp.

Nhưng thực ra sự khác biệt về hiệu suất có thể không đáng kể. Thật vậy, khi kích thước thiết lập đầu vào lớn hơn, hiệu suất sẽ bị chi phối bởi thời gian O(NlogN) để thực hiện sắp xếp. Các bước sao chép là O(N) và sẽ giảm tầm quan trọng khi N tăng lên.

+0

Phiên bản của bạn với Arrays.sort trên thực tế không tối ưu hóa nhiều (hoặc thậm chí không có gì), bởi vì Collections.sort() đã chứa mã tương tự: Object [] a = list.toArray(); Arrays.sort (a, (Comparator) c); ListIterator i = list.listIterator(); cho (int j = 0; j iirekm

+0

@iirekm - sử dụng 'Arrays.asList (mảng)' tránh việc sao chép được thực hiện bằng cách sử dụng trình lặp danh sách. –

+0

Aaah, sao chép thêm như vậy có thể chỉ quan trọng đối với các tập dữ liệu rất lớn. – iirekm

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