Cách ngắn gọn nhất để chuyển đổi Tập hợp <T> thành Danh sách <T>


201

Ví dụ, tôi hiện đang làm điều này:

Set<String> setOfTopicAuthors = ....

List<String> list = Arrays.asList( 
    setOfTopicAuthors.toArray( new String[0] ) );

Bạn có thể đánh bại điều này?


2
Sử dụng java.util.Collection: O (0)
Tim

@Carl, tôi phải gửi Set vào giao diện bên thứ 3 yêu cầu Danh sách. @Tim Tôi ước tôi có thể thay đổi giao diện của bên thứ 3 để sử dụng Bộ sưu tập.
Jacques René Mesrine

1
Tôi hiểu rồi; Không có bất kỳ ràng buộc kỳ lạ nào, tôi sẽ đi với câu trả lời của Rogers. Mặc dù, trừ khi bạn thực sự sử dụng Danh sách một lần nữa, tôi sẽ bỏ qua việc gán nó cho bất cứ điều gì (ví dụ: sử dụng foo.api (new ArrayList <String> (listOfTopicAuthors)) thay vì foo.api (list)).
Carl

2
@ JacquesRenéMesrine: Dòng mã đầu tiên trong câu hỏi là sai lệch: Dự kiến: Set<String> setOfTopicAuthors = ....Thực tế:Set<String> listOfTopicAuthors = ....
realPK

Hoặc một cách khác để làm điều tương tự có thể được List<String> list = Arrays.asList(setOfTopicAuthors.toArray(String[]::new)), chi tiết trong câu trả lời được liên kết.
Naman

Câu trả lời:


432
List<String> list = new ArrayList<String>(listOfTopicAuthors);

1
... và do đó hoàn toàn thách thức các quy ước mã Java: oracle.com/technetwork/java/javase/documentation/ trộm ! :) :)
Håvard Geithus

sau này khi tôi cố truy cập phần tử danh sách, nó gây ra lỗi cho tôi, "java.lang.ClassCastException: java.lang.Integer không thể chuyển sang java.lang.String" ..don; t biết tại sao .. đó là danh sách đơn giản. (int) đó là ... bất kỳ đề nghị?
CoDe

2
Tôi tin vào Java 7 trở lên, bạn có thể bỏ qua tham số loại để ArrayListmang lại: List<String> l = new ArrayList<>(listOfTopicAuthors); Hầu hết súc tích mà không cần sử dụng thư viện bên ngoài?
Brett Duncavage

Nó sẽ ném NullPulumException trong trường hợp listOfTopicAuthorslà null.
w35l3y

91
List<String> l = new ArrayList<String>(listOfTopicAuthors);

4
để trả lời trong cùng một phút với câu trả lời được chấp nhận và không nhận được tín dụng. +1
jayeffkay

@Adamski Tôi kết thúc với một danh sách chỉ số bắt đầu từ 1 thay vì 0, biện pháp khắc phục nào?
Jack

1
@Jack: Điều đó chắc chắn sẽ không xảy ra. Từ Javadoc từ java.util.List: "Danh sách (như mảng Java) không dựa trên."
Adamski

@Adamski Cảm ơn bạn đã phản hồi. Tôi biết các danh sách nên và không dựa trên đó là lý do tại sao điều này rất lạ đối với tôi. Sau khi chuyển đổi tập hợp của tôi thành một danh sách, tôi không thể thực hiện bất kỳ thao tác lặp nào trên nó để tìm kiếm, sắp xếp, v.v. Tôi nhận được một NullPulumException, tuy nhiên khi tôi mong đợi danh sách của mình không có phần tử nào là null và điều kỳ lạ duy nhất tôi nhận thấy là chỉ mục bắt đầu từ 1. Tuy nhiên, nếu tôi chỉ tạo một danh sách bình thường thì chỉ mục bắt đầu từ 0. Lạ không?
Jack

1
@Jack: Nghe có vẻ rất lạ. Nếu bạn đăng mã của mình dưới dạng một câu hỏi riêng biệt, tôi chắc chắn ai đó sẽ có thể giúp bạn.
Adamski

23

Xem xét rằng chúng tôi có Set<String> stringSetchúng tôi có thể sử dụng như sau:

Java 10 (Danh sách không thể thay đổi)

List<String> strList = stringSet.stream().collect(Collectors.toUnmodifiableList());

Java 8 (Danh sách có thể sửa đổi)

import static java.util.stream.Collectors.*;
List<String> stringList1 = stringSet.stream().collect(toList());

Theo tài liệu cho phương pháptoList()

Không có sự đảm bảo nào về loại, tính biến đổi, tính tuần tự hoặc tính an toàn của luồng của Danh sách được trả về; nếu cần thêm quyền kiểm soát Danh sách được trả về, hãy sử dụng toCollection (Nhà cung cấp).

Vì vậy, nếu chúng ta cần một triển khai cụ thể, ví dụ như ArrayListchúng ta có thể thực hiện theo cách này:

List<String> stringList2 = stringSet.stream().
                              collect(toCollection(ArrayList::new));

Java 8 (Danh sách không thể thay đổi)

Chúng ta có thể sử dụng Collections::unmodifiableListphương thức và bọc danh sách được trả về trong các ví dụ trước. Chúng ta cũng có thể viết phương thức tùy chỉnh của riêng mình như:

class ImmutableCollector {
    public static <T> Collector<T, List<T>, List<T>> toImmutableList(Supplier<List<T>> supplier) {
            return Collector.of( supplier, List::add, (left, right) -> {
                        left.addAll(right);
                        return left;
                    }, Collections::unmodifiableList);
        }
}

Và sau đó sử dụng nó như:

List<String> stringList3 = stringSet.stream()
             .collect(ImmutableCollector.toImmutableList(ArrayList::new)); 

Một khả năng khác là sử dụng collectingAndThenphương thức cho phép thực hiện một số biến đổi cuối cùng trước khi trả về kết quả:

    List<String> stringList4 = stringSet.stream().collect(collectingAndThen(
      toCollection(ArrayList::new),Collections::unmodifiableList));

Một điểm cần lưu ý là phương thức Collections::unmodifiableListtrả về một khung nhìn không thể thay đổi của danh sách đã chỉ định, theo tài liệu . Bộ sưu tập chế độ xem không thể thay đổi là một bộ sưu tập không thể thay đổi và cũng là chế độ xem trên bộ sưu tập sao lưu. Lưu ý rằng những thay đổi đối với bộ sưu tập sao lưu vẫn có thể xảy ra và nếu chúng xảy ra, chúng có thể được nhìn thấy qua chế độ xem không thể thay đổi. Nhưng phương thức collector Collectors.unmodifiableListtrả về danh sách thực sự bất biến trong Java 10 .


Tôi sử dụng này để chuyển đổi một Set<Double>đến một List<Doublenơi tập xuất thân từ một LinkedHashMap's .keySet()phương pháp. Eclipse nói với tôi rằng có một kiểu không khớp và tôi không thể chuyển đổi từ Objectsang List<Double>. Bạn có thể cho tôi biết tại sao điều này có thể xảy ra? Tôi đã khắc phục nó bằng cách đúc, nhưng tôi đã tự hỏi tại sao nó lại xảy ra.
Ungeheuer

1
Có, vì Nhà phát triển Java nên sử dụng ngày càng nhiều tính năng Java 8, câu trả lời này tốt hơn 2 câu trả lời ở trên.
Shubham Pandey

13

Hãy thử điều này cho Set :

Set<String> listOfTopicAuthors = .....
List<String> setList = new ArrayList<String>(listOfTopicAuthors); 

Hãy thử điều này cho Bản đồ :

Map<String, String> listOfTopicAuthors = .....
// List of values:
List<String> mapValueList = new ArrayList<String>(listOfTopicAuthors.values());
// List of keys:
List<String> mapKeyList = new ArrayList<String>(listOfTopicAuthors.KeySet());

2

Nếu bạn đang sử dụng Guava, bạn nhập newArrayListphương thức tĩnh từ lớp Danh sách :

List<String> l = newArrayList(setOfAuthors);

0

không thực sự chắc chắn những gì bạn đang làm chính xác thông qua ngữ cảnh mã của bạn nhưng ...

Tại sao làm cho listOfTopicAuthorsbiến ở tất cả?

List<String> list = Arrays.asList((....).toArray( new String[0] ) );

"...." thể hiện tuy nhiên thiết lập của bạn đã hoạt động, cho dù đó là mới hay đến từ một địa điểm khác.

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.