Apakah .asSet (…) ada di API mana pun?

108

Saya mencari cara yang sangat sederhana untuk membuat Set.

Arrays.asList("a", "b" ...) menciptakan sebuah List<String>

Apakah ada yang serupa Set?

cahen
sumber
kemungkinan duplikat Java - dengan mudah mengonversi array ke set
Danilo Piazzalunga
1
bukan, membuat Set dan mengubah Array menjadi Set bukanlah hal yang sama
cahen

Jawaban:

84

Sekarang dengan Java 8 Anda dapat melakukan ini tanpa perlu kerangka pihak ketiga:

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

Lihat Kolektor .

Nikmati!

Tuan Anderson
sumber
4
Saat ini dengan Java 8 ini mungkin jawaban terbaik karena tidak bergantung pada pustaka pihak ke-3 dan dapat dengan mudah disesuaikan dengan jenis koleksi lain, jadi saya menyetel ini sebagai yang diterima. Terima kasih banyak kepada semua orang untuk solusi hebat lainnya. (btw, Set ini bisa berubah)
cahen
3
Nah, siapa yang bilang kalau Java terlalu bertele-tele? Tentu ini jawaban terbaik!
BobDoolittle
Terima kasih banyak @BobDoolittle!
Tn. Anderson
2
Untuk siapa pun yang menggunakan java 9+, harap lihat juga jawaban Holly di bawah ini: stackoverflow.com/a/48025159/229743
Taylor
1
jawaban sempurna Tn. Anderson!
gaurav
63

Menggunakan Jambu biji , sesederhana itu:

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

Atau untuk set yang bisa berubah:

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

Untuk tipe data selengkapnya, lihat panduan pengguna Jambu

Michael Schmeißer
sumber
Apakah ada versi yang tidak dapat diubah dari ini?
cahen
3
@cahen ya: Sets.newHashSet("a", "b")atauSets.newLinkedHashSet("a", "b")
Sean Patrick Floyd
1
Saya menambahkan varian yang bisa berubah ke jawabannya.
Michael Schmeißer
sebenarnya, Sets.newLinkedHashSet()tidak ada dengan tanda tangan itu, maaf
Sean Patrick Floyd
Saya dapat menghapus salah satu jenis argumen:Set<String> mySet = ImmutableSet.of("a", "b");
joshden
55

Anda bisa menggunakan

new HashSet<String>(Arrays.asList("a","b"));
Dev Blanked
sumber
Saya lebih suka melakukan ini kemudian menggunakan versi streaming. Saya hanya dapat mengimpor "asList" secara statis, membuat ini lebih tidak bertele-tele.
Marcio Lucca
24

Untuk kasus khusus set dengan nol atau satu anggota, Anda dapat menggunakan:

java.util.Collections.EMPTY_SET

dan:

java.util.Collections.singleton("A")
Lingkungan Samuel Edwin
sumber
untuk kasus khusus ini, ini kemungkinan merupakan solusi terbaik karena menggunakan API java.util standar
arcuri82
2
java.util.Collections.emptySet()adalah, dalam pikiran saya, lebih disukai daripada EMPTY_SET, karena keamanan tipe. Dari komentar di kelas Koleksi:Unlike the like-named field, this method is parameterized.
Diedit
17

Seperti yang dikatakan orang lain, gunakan:

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

Alasan ini tidak ada di Java adalah karena Arrays.asListmengembalikan daftar berukuran tetap, dengan kata lain:

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

Pengembalian:

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

Tidak ada implementasi JDK dari "ukuran tetap" Setdi dalam Arrayskelas. Kenapa kamu menginginkan ini? A Setmenjamin bahwa tidak ada duplikat, tetapi jika Anda mengetiknya dengan tangan, Anda seharusnya tidak memerlukan fungsionalitas itu ... dan Listmemiliki lebih banyak metode. Kedua antarmuka meluas Collectiondan Iterable.


Seperti yang dikatakan orang lain, gunakan jambu biji Jika Anda benar-benar menginginkan fungsi ini - karena tidak ada di JDK. Lihatlah jawaban mereka (khususnya jawaban Michael Schmeißer) untuk informasi tentang itu.

durron597
sumber
3
Sejauh ini, ini adalah jawaban terbaik, karena menunjukkan apa yang sebenarnya dilakukan oleh Arrays.asList (). Banyak pengembang tampaknya percaya bahwa Arrays.asList () membuat java.util.ArrayList, sementara itu sebenarnya membuat java.util.Arays $ ArrayList (yang hanya dapat diubah sebagian dan tampilan langsung dari array yang mendasarinya)
Sean Patrick Floyd
1
Mengenai mengapa seseorang ingin melakukan ini, alasan paling umum untuk membuat Set (atau List) secara manual adalah di kelas pengujian tempat Anda meneruskan nilai pengujian.
Scott McIntyre
14

Di Java 9, fungsi serupa telah ditambahkan melalui metode pabrik:

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

(Ada juga yang setara List.)

Holly Cummins
sumber
Saya mencoba ini dan mendapat peringatan kompiler bahwa ini bukan metode API.
Philippe Gioseffi
Berikut dokumen java yang relevan: docs.oracle.com/javase/9/docs/api/java/util/Set.html . Selain menggunakan Java 9+ JDK, Anda mungkin perlu menyesuaikan IDE atau alat build untuk menggunakan kepatuhan Java 9 (misalnya, untuk maven, langkahnya akan serupa dengan yang ada di sini, tetapi disetel ke 1.9: stackoverflow.com/ pertanyaan / 16798066 /… )
Holly Cummins
Berharap kita bisa menggunakan Java 9 .. Kita hidup di masa lalu! :(
jDub9
itu bagus tetapi memiliki beberapa batasan pada ukuran argumen ...
Radoslav Ivanov
3

Tidak, tetapi Anda bisa melakukannya seperti ini

new HashSet<String>(Arrays.asList("a", "b", ...));
Evgeniy Dorofeev
sumber
2

Di jambu biji bisa digunakan

Set<String> set = Sets.newHashSet("a","b","c");

newHashSet

OscarRyz
sumber
2

Berikut sedikit metode yang dapat Anda gunakan

  /**
   * 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));
  }
Stuart Clark
sumber
1

Cara lain untuk melakukannya menggunakan Java 8 dan enum adalah:

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

Lihat EnumSet .

Saya akan merekomendasikan analisis kinerja antara pendekatan ini dan

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

karena jika Anda memiliki lebih dari lima elemen, javadoc dari metode menyatakan yang mungkin menjadi masalah kinerja seperti yang Anda lihat di javadoc dari Set.Of (E, E ...) .

Philippe Gioseffi
sumber