Làm cách nào để sắp xếp Tập hợp thành Danh sách trong Java?


169

Trong Java, tôi có một Setvà tôi muốn biến nó thành một sắp xếp List. Có một phương pháp trong java.util.Collectionsgói sẽ làm điều này cho tôi?

Câu trả lời:


214

Câu trả lời được cung cấp bởi OP không phải là tốt nhất. Nó không hiệu quả, vì nó tạo ra một mảng mới List không cần thiết. Ngoài ra, nó đưa ra các cảnh báo "không được kiểm soát" vì các vấn đề an toàn kiểu xung quanh các mảng chung.

Thay vào đó, sử dụng một cái gì đó như thế này:

public static
<T extends Comparable<? super T>> List<T> asSortedList(Collection<T> c) {
  List<T> list = new ArrayList<T>(c);
  java.util.Collections.sort(list);
  return list;
}

Đây là một ví dụ sử dụng:

Map<Integer, String> map = new HashMap<Integer, String>();
/* Add entries to the map. */
...
/* Now get a sorted list of the *values* in the map. */
Collection<String> unsorted = map.values();
List<String> sorted = Util.asSortedList(unsorted);

3
Cảm ơn! Đó là SuppressWarnings luôn làm phiền tôi.
Jeremy Stein

4
@sunleo UtilLớp là lớp chứa asSortedList()phương thức tôi đã viết. Nói cách khác, bạn tự viết Utillớp và đặt mã đó vào đó.
erickson

1
ha ha tôi nghĩ nó từ gói mặc định như java.util ok cảm ơn bạn.
sunleo

3
Đây có thể là một chức năng chung chung tốt đẹp, nhưng thực tế là nó vẫn không hiệu quả. Cân nhắc sắp xếp tại chỗ bằng cách đảm bảo rằng bạn đã đặt đúng bộ chứa của mình. Ngoài ra, hãy xem xét việc sử dụng TreeSet như một nơi chứa dữ liệu trực tiếp của bạn. Nếu dữ liệu của bạn cần phải là duy nhất và bạn cần một Bộ, sau đó sử dụng TreeSet, bắt hai con ruồi trong một swat.
YoYo

1
Lưu ý cho những người chỉ đọc câu trả lời hàng đầu: Hãy xem câu trả lời của nschum bên dưới, sử dụng các luồng của Java 8. Nếu bạn có thể sử dụng Java 8, hãy dùng nó. chúng linh hoạt và hiệu quả hơn.
Felk

74

Bộ sắp xếp:

return new TreeSet(setIWantSorted);

hoặc là:

return new ArrayList(new TreeSet(setIWantSorted));

Đây là suy nghĩ đầu tiên của tôi, nhưng người hỏi muốn có một Danh sách
Alex B

@Alex: Cách tiếp cận này vẫn có thể được sử dụng; trả về ArrayList mới (Treeset mới (setIWantSortic))
Jonik

1
Tôi thực sự đã sử dụng giải pháp này, nhưng tôi sẽ không khuyên điều này. Như tài liệu về các trạng thái của Treset (xem download.oracle.com/javase/1.4.2/docs/api/java/util/ ,), nó sử dụng hiệu quả phương thức so sánh () thay vì phương thức equals () - vì vậy nếu bạn có hai đối tượng trong tập hợp có cùng kết quả bằng (), chúng sẽ được xem là trùng lặp và, do đó, sẽ không được thêm vào Treeset. Coi chừng.
fwielstra

24
@fwielstra: Làm thế nào bạn có thể có các đối tượng bằng nhau trong đầu vào vì đầu vào cũng là một Set?
ryanprayogo

2
@ryanprayogo Điều đáng nói, vì new TreeSetchấp nhận Collections, không chỉ Sets. Không phải ai đang đọc câu trả lời này cũng sẽ sử dụng Set, mặc dù đó là câu hỏi ban đầu.
Chris

44
List myList = new ArrayList(collection);
Collections.sort(myList);

Tuy nhiên, nên thực hiện các mẹo nhỏ. Thêm hương vị với Generics khi áp dụng.


Tôi đã có một đoạn hữu ích mà tôi muốn quyên góp cho cộng đồng. Khi tôi tìm kiếm thông tin, tôi không thể tìm thấy nó. Tôi đã cố gắng để làm cho công việc của người tiếp theo dễ dàng hơn. stackoverflow.com/questions/18557/ trộm
Jeremy Stein

1
Vâng, chắc chắn, nhưng liên kết mà bạn cung cấp thực sự đang nói về một câu hỏi thực sự (tức là những câu hỏi không có câu trả lời, sau đó tìm nó). Câu hỏi của bạn ở đây chỉ để đưa ra câu trả lời ... Tôi thực sự có thể nhập hàng trăm câu hỏi và tự trả lời; đó không phải là vấn đề!
Seb

5
@Seb: Tôi không đồng ý. Tôi không thấy có gì sai với câu hỏi này. Đó rõ ràng không phải là một câu hỏi cực kỳ đơn giản, và bây giờ anh ta biết một cách tốt hơn so với trước đây!
Michael Myers

3
Đó một câu hỏi thực sự, nhưng tôi đã tìm thấy câu trả lời cho chính mình sau khi Google xuất hiện ngắn. Stackoverflow không tồn tại vào thời điểm đó. Tôi đã có nó được đăng trên trang web của tôi và nó đã giúp đỡ người khác, vì vậy tôi nghĩ rằng nó có thể hữu ích ở đây.
Jeremy Stein

Phần thưởng: Và nếu bạn tình cờ sắp xếp loại đối tượng của riêng mình thì bạn luôn có thể thực hiện Comparablevà ghi đè compareTophương thức.
nabster

42

Đây là cách bạn có thể làm điều đó với Luồng của Java 8:

mySet.stream().sorted().collect(Collectors.toList());

hoặc với một bộ so sánh tùy chỉnh:

mySet.stream().sorted(myComparator).collect(Collectors.toList());

9

Luôn an toàn khi sử dụng giao diện So sánh hoặc So sánh để cung cấp triển khai sắp xếp (nếu đối tượng không phải là lớp Chuỗi hoặc Trình bao bọc cho các kiểu dữ liệu nguyên thủy). Như một ví dụ cho việc triển khai so sánh để sắp xếp nhân viên dựa trên tên

    List<Employees> empList = new LinkedList<Employees>(EmpSet);

    class EmployeeComparator implements Comparator<Employee> {

            public int compare(Employee e1, Employee e2) {
                return e1.getName().compareTo(e2.getName());
            }

        }

   Collections.sort(empList , new EmployeeComparator ());

Bộ so sánh rất hữu ích khi bạn cần có thuật toán sắp xếp khác nhau trên cùng một đối tượng (Nói tên emp, lương emp, v.v.). Sắp xếp chế độ đơn có thể được thực hiện bằng cách sử dụng giao diện so sánh trong đối tượng được yêu cầu.


5

Không có phương pháp duy nhất để làm điều đó. Dùng cái này:

@SuppressWarnings("unchecked")
public static <T extends Comparable> List<T> asSortedList(Collection<T> collection) {
  T[] array = collection.toArray(
    (T[])new Comparable[collection.size()]);
  Arrays.sort(array);
  return Arrays.asList(array);
}

Ngoài ra còn có một hàm Collections.sort, nhưng tôi nghĩ nó cũng làm điều tương tự. Dù sao +1.
CookieOfFortune

1
Bộ sưu tập.sort lấy một danh sách làm tham số.
Jeremy Stein

3

Bạn có thể chuyển đổi một tập hợp thành một ArrayList, nơi bạn có thể sắp xếp việc ArrayListsử dụng Collections.sort(List).

Đây là mã:

keySet = (Set) map.keySet();
ArrayList list = new ArrayList(keySet);     
Collections.sort(list);

3
TreeSet sortedset = new TreeSet();
sortedset.addAll(originalset);

list.addAll(sortedset);

where originalset = unsort set and list = danh sách được trả về


TreeSet cũng loại bỏ danh sách có thể dẫn đến kết quả sai nếu bạn không cho rằng điều đó.
anthonymousonori

2

@Jeremy Stein Tôi muốn thực hiện cùng một mã. Tôi cũng muốn sắp xếp tập hợp thành danh sách, vì vậy thay vì sử dụng Tập tôi đã chuyển đổi các giá trị tập hợp thành Danh sách và sắp xếp danh sách đó theo một biến. Mã này đã giúp tôi,

set.stream().sorted(Comparator.comparing(ModelClassName::sortingVariableName)).collect(Collectors.toList());

0

Tôi đang sử dụng mã này, mà tôi thấy thực tế hơn câu trả lời được chấp nhận ở trên:

List<Thing> thingList = new ArrayList<>(thingSet);
thingList.sort((thing1, thing2) -> thing1.getName().compareToIgnoreCase(thing2.getName()));
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.