Czy .asSet (…) istnieje w jakimkolwiek interfejsie API?

108

Szukam bardzo prostego sposobu na stworzenie Zestawu.

Arrays.asList("a", "b" ...) tworzy plik List<String>

Czy jest coś podobnego do Set?

cahen
źródło
możliwy duplikat Javy - łatwo przekonwertować tablicę na zestaw
Danilo Piazzalunga
1
tak nie jest, tworzenie zestawu i konwertowanie tablicy na zestaw to nie to samo
cahen

Odpowiedzi:

84

Teraz dzięki Java 8 możesz to zrobić bez konieczności korzystania z platformy zewnętrznej:

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

Zobacz Kolekcjonerzy .

Cieszyć się!

Panie Anderson
źródło
4
Obecnie w przypadku Java 8 jest to prawdopodobnie najlepsza odpowiedź, ponieważ nie zależy ona od bibliotek innych firm i można ją łatwo dostosować do innych typów kolekcji, więc ustawiam ją jako akceptowaną. Serdeczne podziękowania dla wszystkich za pozostałe świetne rozwiązania. (przy okazji, ten zestaw jest zmienny)
cahen
3
Kto powiedział, że Java jest zbyt szczegółowa? Oczywiście to najlepsza odpowiedź!
BobDoolittle
Wielkie dzięki @BobDoolittle!
Pan Anderson
2
Dla każdego, kto używa Java 9+, zapoznaj się również z odpowiedzią Holly poniżej: stackoverflow.com/a/48025159/229743
Taylor
1
bezbłędna odpowiedź, panie Anderson!
gaurav
64

Korzystanie z guawy jest takie proste:

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

Lub dla zmiennego zestawu:

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

Więcej typów danych można znaleźć w podręczniku użytkownika Guava

Michael Schmeißer
źródło
Czy istnieje niezmienna wersja tego?
cahen
3
@cahen yes: Sets.newHashSet("a", "b")lubSets.newLinkedHashSet("a", "b")
Sean Patrick Floyd
1
Dodałem zmienny wariant do odpowiedzi.
Michael Schmeißer
właściwie Sets.newLinkedHashSet()nie istnieje z tym podpisem, przepraszam
Sean Patrick Floyd
Udało mi się usunąć jeden z argumentów typu:Set<String> mySet = ImmutableSet.of("a", "b");
joshden
55

Możesz użyć

new HashSet<String>(Arrays.asList("a","b"));
Dev Blanked
źródło
Wolałbym to zrobić niż użyć wersji strumieniowej. Mogę po prostu zaimportować statycznie „asList”, dzięki czemu jest to jeszcze mniej szczegółowe.
Marcio Lucca
24

W szczególnych przypadkach zestawów z zerowym lub jednym składnikiem możesz użyć:

java.util.Collections.EMPTY_SET

i:

java.util.Collections.singleton("A")
Samuel Edwin Ward
źródło
w tych specjalnych przypadkach jest to prawdopodobnie najlepsze rozwiązanie, ponieważ korzysta ze standardowego interfejsu API java.util
arcuri82
2
java.util.Collections.emptySet()jest moim zdaniem preferowany względem EMPTY_SET ze względu na bezpieczeństwo typów. Z komentarzy w klasie Kolekcje:Unlike the like-named field, this method is parameterized.
Eddified
17

Jak powiedzieli inni, użyj:

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

Powodem tego, że nie istnieje w Javie, jest to, że Arrays.asListzwraca listę o stałym rozmiarze, innymi słowy:

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

Zwroty:

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

Nie ma realizacja JDK o „stałej wielkości” Setwewnątrz Arraysklasy. Dlaczego tego chcesz? A Setgwarantuje, że nie ma duplikatów, ale jeśli wpisując je ręcznie, nie ma potrzeby tej funkcjonalności ... i Listma więcej metod. Oba interfejsy rozszerzają Collectioni Iterable.


Jak powiedzieli inni, użyj guawy, jeśli naprawdę chcesz tej funkcji - ponieważ nie ma jej w JDK. Sprawdź ich odpowiedzi (w szczególności odpowiedź Michaela Schmeißera), aby uzyskać informacje na ten temat.

durron597
źródło
3
Jak dotąd jest to najlepsza odpowiedź, ponieważ wskazuje, co faktycznie robi Arrays.asList (). Wydaje się, że wielu programistów uważa, że ​​Arrays.asList () tworzy java.util.ArrayList, podczas gdy w rzeczywistości tworzy java.util.Arrays $ ArrayList (która jest tylko częściowo zmienna i umożliwia podgląd na żywo podstawowej tablicy)
Sean Patrick Floyd
1
Jeśli chodzi o powód, dla którego ktoś chciałby to zrobić, najczęstszym powodem tworzenia zestawu (lub listy) ręcznie jest klasa testowa, w której przekazujesz wartości testowe.
Scott McIntyre
14

W Javie 9 podobna funkcja została dodana metodami fabrycznymi:

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

(Istnieją również odpowiedniki dla List.)

Holly Cummins
źródło
Próbowałem tego i otrzymałem ostrzeżenie kompilatora, że ​​to nie jest metoda API.
Philippe Gioseffi
Oto odpowiedni dokument java: docs.oracle.com/javase/9/docs/api/java/util/Set.html . Oprócz używania Java 9+ JDK może być konieczne dostosowanie IDE lub narzędzia do budowania, aby korzystało ze zgodności z Javą 9 (na przykład dla maven byłoby to podobne kroki do tych tutaj, ale ustawione na 1.9: stackoverflow.com/ pytania / 16798066 /… )
Holly Cummins,
Szkoda, że ​​nie możemy używać Java 9 .. Żyjemy w przeszłości! :(
jDub9
to dobrze, ale mam pewne ograniczenia co do wielkości argumentów ...
Radoslav Ivanov
3

Nie, ale możesz to zrobić w ten sposób

new HashSet<String>(Arrays.asList("a", "b", ...));
Evgeniy Dorofeev
źródło
2

W guawie możesz użyć

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

newHashSet

OscarRyz
źródło
2

Oto mała metoda, której możesz użyć

  /**
   * 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
źródło
1

Innym sposobem na zrobienie tego za pomocą Java 8 i wyliczeń byłoby:

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

Zobacz EnumSet .

Poleciłbym analizę wydajności między tym podejściem a

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

ponieważ jeśli masz więcej niż pięć elementów, javadoc metody stwierdza, że ​​mogą to być problemy z wydajnością, jak widać w javadoc Set.Of (E, E ...) .

Philippe Gioseffi
źródło