Existiert .asSet (…) in einer API?


Antworten:


84

Mit Java 8 können Sie dies jetzt tun, ohne ein Framework von Drittanbietern zu benötigen:

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

Siehe Sammler .

Genießen!


4
Heutzutage ist dies mit Java 8 wahrscheinlich die beste Antwort, da es nicht von Bibliotheken von Drittanbietern abhängt und leicht an andere Sammlungstypen angepasst werden kann. Daher setze ich dies als die akzeptierte. Vielen Dank an alle für die anderen tollen Lösungen. (Übrigens ist dieses Set veränderlich)
cahen

3
Wer hat gesagt, dass Java zu ausführlich ist? Das ist natürlich die beste Antwort!
BobDoolittle

Vielen Dank @BobDoolittle!
Mr. Anderson

2
Für alle, die Java 9+ verwenden, lesen
Taylor

1
makellose Antwort Mr. Anderson!
Gaurav

63

Mit Guava ist es so einfach:

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

Oder für eine veränderliche Menge:

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

Weitere Datentypen finden Sie im Guava-Benutzerhandbuch


Gibt es eine unveränderliche Version davon?
Cahen

3
@ Cahen ja: Sets.newHashSet("a", "b")oderSets.newLinkedHashSet("a", "b")
Sean Patrick Floyd

1
Ich habe der Antwort eine veränderbare Variante hinzugefügt.
Michael Schmeißer

existiert eigentlich Sets.newLinkedHashSet()nicht mit dieser Unterschrift, sorry
Sean Patrick Floyd

Ich konnte eines der Set<String> mySet = ImmutableSet.of("a", "b");
Typargumente


24

Für die Sonderfälle von Sätzen mit null oder einem Mitglied können Sie Folgendes verwenden:

java.util.Collections.EMPTY_SET

und:

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

Für diese speziellen Fälle ist es wahrscheinlich die beste Lösung, da es die Standard-API java.util verwendet
arcuri82

2
java.util.Collections.emptySet()wird meiner Meinung nach aus Gründen der Typensicherheit EMPTY_SET vorgezogen. Aus den Kommentaren in der Collections-Klasse:Unlike the like-named field, this method is parameterized.
Eddified

17

Wie andere gesagt haben, verwenden Sie:

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

Der Grund, warum dies in Java nicht existiert, ist, dass Arrays.asListeine Liste mit fester Größe zurückgegeben wird, mit anderen Worten:

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

Kehrt zurück:

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

Es gibt keine JDK-Implementierung einer "festen Größe" Setinnerhalb der ArraysKlasse. Warum willst du das? A Setgarantiert, dass es keine Duplikate gibt, aber wenn Sie sie von Hand eingeben, sollten Sie diese Funktionalität nicht benötigen ... und Listverfügt über mehr Methoden. Beide Schnittstellen erweitern Collectionund Iterable.


Verwenden Sie, wie andere gesagt haben, Guave, wenn Sie diese Funktionalität wirklich wollen - da sie nicht im JDK enthalten ist. Informationen dazu finden Sie in ihren Antworten (insbesondere in der Antwort von Michael Schmeißer).


3
Dies ist die bisher beste Antwort, da sie darauf hinweist, was Arrays.asList () tatsächlich tut. Viele Entwickler scheinen zu glauben, dass Arrays.asList () eine java.util.ArrayList erstellt, während tatsächlich eine java.util.Arrays $ ArrayList erstellt wird (die nur teilweise veränderbar ist und eine Live-Ansicht des zugrunde liegenden Arrays enthält)
Sean Patrick Floyd

1
Der häufigste Grund, warum jemand dies tun möchte, ist der häufigste Grund, einen Satz (oder eine Liste) von Hand zu erstellen, in einer Testklasse, in der Sie Testwerte übergeben.
Scott McIntyre

14

In Java 9 wurde eine ähnliche Funktion über Factory-Methoden hinzugefügt:

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

(Es gibt auch Äquivalente für List.)


Ich habe dies versucht und eine Compiler-Warnung erhalten, dass dies keine API-Methode ist.
Philippe Gioseffi

Hier ist das relevante Java-Dokument: docs.oracle.com/javase/9/docs/api/java/util/Set.html . Zusätzlich zur Verwendung eines Java 9+ JDK müssen Sie möglicherweise Ihre IDE oder Ihr Build-Tool anpassen, um die Java 9-Konformität zu verwenden (für Maven wären dies beispielsweise ähnliche Schritte wie hier, jedoch auf 1.9 festgelegt: stackoverflow.com/ Fragen / 16798066 /… )
Holly Cummins

Ich wünschte, wir könnten Java 9 verwenden. Wir leben in der Vergangenheit! :(
jDub9

das ist gut, hat aber einige Einschränkungen hinsichtlich der Größe der Argumente ...
Radoslav Ivanov



2

Hier ist eine kleine Methode, die Sie verwenden können

  /**
   * 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

Eine andere Möglichkeit, dies mit Java 8 und Enums zu tun, wäre:

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

Siehe EnumSet .

Ich würde eine Leistungsanalyse zwischen diesem Ansatz und empfehlen

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

Denn wenn Sie mehr als fünf Elemente haben, gibt das Javadoc der Methode an, dass es sich möglicherweise um Leistungsprobleme handelt, wie Sie im Javadoc von Set.Of (E, E ...) sehen können .

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.