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


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!


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


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"));

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")

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.


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.)


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



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));
  }

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 ...) .

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.