.AsSet (…) existe-t-il dans une API?

108

Je recherche un moyen très simple de créer un ensemble.

Arrays.asList("a", "b" ...) crée un List<String>

Y a-t-il quelque chose de similaire pour Set?

cahen
la source
duplication possible de Java - convertir facilement un tableau en ensemble
Danilo Piazzalunga
1
ce n'est pas le cas, créer un ensemble et convertir un tableau en un ensemble n'est pas la même chose
cahen

Réponses:

84

Désormais, avec Java 8, vous pouvez le faire sans avoir besoin d'un framework tiers:

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

Voir les collectionneurs .

Prendre plaisir!

M. Anderson
la source
4
De nos jours, avec Java 8, c'est probablement la meilleure réponse car elle ne dépend pas de bibliothèques tierces et peut être facilement adaptée à d'autres types de collections, donc je la définis comme acceptée. Un grand merci à tous pour les autres excellentes solutions. (btw, cet ensemble est mutable)
cahen
3
Maintenant, qui a dit que Java était trop bavard? Bien sûr, c'est la meilleure réponse!
BobDoolittle
Merci beaucoup @BobDoolittle!
M. Anderson
2
Pour tous ceux qui utilisent java 9+, veuillez également consulter la réponse de Holly ci-dessous: stackoverflow.com/a/48025159/229743
Taylor
1
réponse impeccable M. Anderson!
gaurav
63

En utilisant Guava , c'est aussi simple que cela:

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

Ou pour un ensemble mutable:

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

Pour plus de types de données, consultez le guide de l'utilisateur de Guava

Michael Schmeißer
la source
Existe-t-il une version non immuable de cela?
cahen
3
@cahen yes: Sets.newHashSet("a", "b")orSets.newLinkedHashSet("a", "b")
Sean Patrick Floyd
1
J'ai ajouté une variante mutable à la réponse.
Michael Schmeißer
en fait, Sets.newLinkedHashSet()n'existe pas avec cette signature, désolé
Sean Patrick Floyd
J'ai pu supprimer l'un des arguments de type:Set<String> mySet = ImmutableSet.of("a", "b");
joshden
55

Vous pourriez utiliser

new HashSet<String>(Arrays.asList("a","b"));
Dev masqué
la source
Je préférerais faire cela puis utiliser la version stream. Je peux simplement importer statiquement "asList", ce qui rend cela encore moins détaillé.
Marcio Lucca
24

Pour les cas particuliers des ensembles avec zéro ou un membre, vous pouvez utiliser:

java.util.Collections.EMPTY_SET

et:

java.util.Collections.singleton("A")
Samuel Edwin Ward
la source
pour ces cas particuliers, c'est probablement la meilleure solution car elle utilise l'API standard java.util
arcuri82
2
java.util.Collections.emptySet()est, dans mon esprit, préféré à EMPTY_SET, en raison de la sécurité du type. D'après les commentaires de la classe Collections:Unlike the like-named field, this method is parameterized.
Édité le
17

Comme d'autres l'ont dit, utilisez:

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

La raison pour laquelle cela n'existe pas en Java est que Arrays.asListrenvoie une liste de taille fixe, en d'autres termes:

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

Retour:

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

Il n'y a pas d'implémentation JDK d'une "taille fixe" Setà l'intérieur de la Arraysclasse. Pourquoi vous voulez ceci? A Setgarantit qu'il n'y a pas de doublons, mais si vous les tapez à la main, vous ne devriez pas avoir besoin de cette fonctionnalité ... et Lista plus de méthodes. Les deux interfaces étendent Collectionet Iterable.


Comme d'autres l'ont dit, utilisez goyave si vous voulez vraiment cette fonctionnalité - car elle n'est pas dans le JDK. Regardez leurs réponses (en particulier la réponse de Michael Schmeißer) pour plus d'informations à ce sujet.

durron597
la source
3
C'est la meilleure réponse à ce jour, car elle indique ce que fait réellement Arrays.asList (). De nombreux développeurs semblent croire que Arrays.asList () crée un java.util.ArrayList, alors qu'il crée en fait un java.util.Arrays $ ArrayList (qui n'est que partiellement modifiable et une vue en direct du tableau sous-jacent)
Sean Patrick Floyd
1
Quant à savoir pourquoi quelqu'un voudrait faire cela, la raison la plus courante pour construire un ensemble (ou une liste) à la main est dans une classe de test où vous passez des valeurs de test.
Scott McIntyre
14

Dans Java 9, une fonction similaire a été ajoutée via des méthodes d'usine:

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

(Il existe également des équivalents List.)

Holly Cummins
la source
J'ai essayé cela et j'ai reçu un avertissement du compilateur indiquant qu'il ne s'agissait pas d'une méthode API.
Philippe Gioseffi
Voici le document java pertinent: docs.oracle.com/javase/9/docs/api/java/util/Set.html . En plus d'utiliser un JDK Java 9+, vous devrez peut-être ajuster votre IDE ou votre outil de construction pour utiliser la conformité Java 9 (par exemple, pour maven, les étapes seraient similaires à celles ici, mais définies sur 1.9: stackoverflow.com/ questions / 16798066 /… )
Holly Cummins
J'aimerais pouvoir utiliser Java 9 .. Nous vivons dans le passé! :(
jDub9
c'est bien mais avoir quelques restrictions sur la taille des arguments ...
Radoslav Ivanov
3

Non mais tu peux le faire comme ça

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

Dans la goyave, vous pouvez utiliser

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

newHashSet

OscarRyz
la source
2

Voici une petite méthode que vous pouvez utiliser

  /**
   * 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
la source
1

Une autre façon de le faire en utilisant Java 8 et les énumérations serait:

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

Voir EnumSet .

Je recommanderais une analyse des performances entre cette approche et

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

car si vous avez plus de cinq éléments, le javadoc de la méthode indique que cela peut être des problèmes de performances comme vous pouvez le voir dans le javadoc de Set.Of (E, E ...) .

Philippe Gioseffi
la source