.AsSet (…) có tồn tại trong bất kỳ API nào không?


108

Tôi đang tìm một cách rất đơn giản để tạo Tập hợp.

Arrays.asList("a", "b" ...) tạo ra một List<String>

Có điều gì tương tự cho Set?



1
nó không phải, tạo Tập và chuyển đổi một mảng đến một Set không phải là điều tương tự
cahen

Câu trả lời:


84

Giờ đây với Java 8, bạn có thể thực hiện việc này mà không cần đến khuôn khổ của bên thứ ba:

Set<String> set = Stream.of("a","b","c").collect(Collectors.toSet());

Xem Người sưu tầm .

Thưởng thức!


4
Ngày nay với Java 8, đây có lẽ là câu trả lời tốt nhất vì nó không phụ thuộc vào thư viện của bên thứ 3 và có thể dễ dàng điều chỉnh với các loại bộ sưu tập khác, vì vậy tôi đang đặt đây là loại được chấp nhận. Rất cám ơn mọi người vì những giải pháp tuyệt vời khác. (btw, Set này là có thể thay đổi)
cahen

3
Bây giờ, có ai nói rằng Java quá dài dòng không? Tất nhiên đây là câu trả lời tốt nhất!
BobDoolittle

Cảm ơn rất nhiều @BobDoolittle!
Ông Anderson

2
Đối với bất cứ ai sử dụng java 9 + hài lòng cũng thấy câu trả lời của Holly dưới đây: stackoverflow.com/a/48025159/229743
Taylor

1
câu trả lời hoàn hảo ông Anderson!
gaurav

63

Sử dụng Ổi , nó chỉ đơn giản như vậy:

Set<String> mySet = ImmutableSet.<String> of("a", "b");

Hoặc đối với một tập hợp có thể thay đổi:

Set<String> mySet = Sets.newHashSet("a", "b")

Để biết thêm các loại dữ liệu, hãy xem hướng dẫn sử dụng Guava


Có một phiên bản bất biến của điều này không?
cahen

3
@cahen yes: Sets.newHashSet("a", "b")hoặcSets.newLinkedHashSet("a", "b")
Sean Patrick Floyd

1
Tôi đã thêm một biến thể có thể thay đổi vào câu trả lời.
Michael Schmeißer

thực sự, Sets.newLinkedHashSet()không tồn tại với chữ ký đó, xin lỗi
Sean Patrick Floyd

Tôi đã có thể loại bỏ một trong những lập luận kiểu:Set<String> mySet = ImmutableSet.of("a", "b");
joshden

54

Bạn đã có thể sử dụng

new HashSet<String>(Arrays.asList("a","b"));

24

Đối với các trường hợp đặc biệt của tập hợp không có hoặc một thành viên, bạn có thể sử dụng:

java.util.Collections.EMPTY_SET

và:

java.util.Collections.singleton("A")

đối với những trường hợp đặc biệt, có khả năng giải pháp tốt nhất vì nó sử dụng API java.util chuẩn
arcuri82

2
java.util.Collections.emptySet()theo suy nghĩ của tôi, được ưu tiên hơn EMPTY_SET, do tính an toàn của loại. Từ các nhận xét trong lớp Bộ sưu tập:Unlike the like-named field, this method is parameterized.
Đã chỉnh sửa

17

Như những người khác đã nói, hãy sử dụng:

new HashSet<String>(Arrays.asList("a","b"));

Lý do điều này không tồn tại trong Java là nó Arrays.asListtrả về một danh sách có kích thước cố định, nói cách khác:

public static void main(String a[])
{
  List<String> myList = Arrays.asList("a", "b");
  myList.add("c");
}

Lợi nhuận:

Exception in thread "main" java.lang.UnsupportedOperationException
    at java.util.AbstractList.add(Unknown Source)
    at java.util.AbstractList.add(Unknown Source)

Không có triển khai JDK của một "kích thước cố định" Setbên trong Arrayslớp. Tại sao bạn muốn điều này? A Setđảm bảo rằng không có bản sao, nhưng nếu bạn đang gõ chúng bằng tay, bạn không cần chức năng đó ... và Listcó nhiều phương pháp hơn. Cả hai giao diện đều mở rộng CollectionIterable.


Như những người khác đã nói, hãy sử dụng ổi Nếu bạn thực sự muốn chức năng này - vì nó không có trong JDK. Hãy xem câu trả lời của họ (cụ thể là câu trả lời của Michael Schmeißer) để biết thông tin về điều đó.


3
Đây là câu trả lời tốt nhất cho đến nay, vì nó chỉ ra những gì Arrays.asList () thực sự làm. Nhiều nhà phát triển dường như tin rằng Arrays.asList () tạo ra java.util.ArrayList, trong khi nó thực sự tạo ra java.util.Arrays $ ArrayList (chỉ có thể thay đổi một phần và là chế độ xem trực tiếp của mảng bên dưới)
Sean Patrick Floyd

1
Về lý do tại sao ai đó muốn làm điều này, lý do phổ biến nhất để tạo một Tập hợp (hoặc Danh sách) bằng tay là trong một lớp thử nghiệm nơi bạn đang vượt qua các giá trị thử nghiệm.
Scott McIntyre

14

Trong Java 9, chức năng tương tự đã được thêm vào thông qua các phương thức gốc:

Set<String> oneLinerSet = Set.of("a", "b", ...);

(Cũng có những thứ tương đương List.)


Tôi đã thử điều này và nhận được cảnh báo trình biên dịch rằng đây không phải là một phương thức API.
Philippe Gioseffi

Đây là tài liệu java có liên quan: docs.oracle.com/javase/9/docs/api/java/util/Set.html . Cũng như sử dụng Java 9+ JDK, bạn có thể cần điều chỉnh IDE hoặc công cụ xây dựng của mình để sử dụng tính tuân thủ của Java 9 (ví dụ: đối với maven, nó sẽ tương tự các bước ở đây, nhưng được đặt thành 1.9: stackoverflow.com/ câu hỏi / 16798066 /… )
Holly Cummins

Ước gì chúng ta có thể sử dụng Java 9 .. Chúng ta đang sống trong quá khứ! :(
jDub9 26/02/19

đó là tốt, nhưng có một số hạn chế về kích thước của các đối số ...
Radoslav Ivanov

3

Không nhưng bạn có thể làm như thế này

new HashSet<String>(Arrays.asList("a", "b", ...));


2

Đây là một phương pháp nhỏ bạn có thể sử dụng

  /**
   * Utility method analogous to {@link java.util.Arrays#asList(Object[])}
   *
   * @param ts
   * @param <T>
   * @return the set of all the parameters given.
   */
  @SafeVarargs
  @SuppressWarnings("varargs")
  public static <T> Set<T> asSet(T... ts) {
    return new HashSet<>(Arrays.asList(ts));
  }

1

Một cách khác để làm điều đó bằng cách sử dụng Java 8 và enums sẽ là:

Set<String> set = EnumSet.of(StandardOpenOption.CREATE, StandardOpenOption.READ);

Xem EnumSet .

Tôi muốn giới thiệu phân tích hiệu suất giữa phương pháp này và

Set<String> set = Stream.of(StandardOpenOption.CREATE, StandardOpenOption.READ).collect(Collectors.toSet());

bởi vì nếu bạn có nhiều hơn năm phần tử, javadoc của phương thức nói rằng đó có thể là các vấn đề về hiệu suất như bạn có thể thấy trong javadoc của Set.Of (E, E ...) .

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.