web-dev-qa-db-fra.com

Qu'est-ce que EnumSet signifie vraiment?

J'ai l'exemple suivant:

import Java.util.EnumSet;
import Java.util.Iterator;

public class SizeSet {

    public static void main(String[] args) {
        EnumSet largeSize = EnumSet.of(Size.XL,Size.XXL,Size.XXXL);
        for(Iterator it = largeSize.iterator();it.hasNext();){
            Size size = (Size)it.next();
            System.out.println(size);
        }
    }
}


enum Size {
  S, M, L, XL, XXL, XXXL;

}

Dans ce code, je peux comprendre que l’énumération crée un type de tailles Enum.

Ma question est la suivante: largeSize est-il un objet de type EnumSet? Qu'est-ce que cela signifie vraiment? Je veux vraiment mieux comprendre.

64
Adam

Comme pour toute variable, son type se trouve dans sa déclaration:

EnumSet largeSize

Donc oui, largeSize (qui devrait être nommé largeSizes puisqu'il s'agit d'une collection) est de type EnumSet. Il devrait également être généralisé, et donc être déclaré comme

EnumSet<Size> largeSizes

Cela signifie que largeSizes est de type EnumSet. Un EnumSet est un Set qui contient une instance enum d'un type enum spécifique, de manière plus efficace que d'autres implémentations Set (comme HashSet, TreeSet, etc.). Pour savoir ce qu’est un EnumSet, lisez son API .

42
JB Nizet

Simplifier votre code

EnumSet<Size> largeSize = EnumSet.of(Size.XXXL, Size.XXL, Size.XL, Size.L);
for(Size size: largeSize)
    System.out.print(size+" ");

Vous pouvez voir que largeSize est un ensemble standard, sauf qu'il est conçu pour stocker des énumérations. En quoi est-ce différent? Premièrement, la machine virtuelle Java connaît toutes les valeurs possibles de l'ensemble, ce qui signifie qu'au lieu de stocker tous les objets, elle peut utiliser une image bitmap, où 1 signifie que l'élément est présent et 0 que ce n'est pas le cas. Cela signifie également que l'ordre de l'ensemble est l'ordre des valeurs ordinales, c'est-à-dire l'ordre dans lequel elles ont été définies. C'est pourquoi cela imprime

L XL XXL XXXL

Si vous voulez en savoir plus en détail, je vous suggère de lire la source de ce cours.

38
Peter Lawrey

Un simple Enum est une liste de valeurs que vous ne pouvez sélectionner qu’une à la fois. En utilisant votre exemple, une taille ne peut être que l'une des tailles S, M, L, etc. pour un tissu donné. Vous pouvez utiliser des constantes simples à la place de Enum, mais cela présente des avantages de lisibilité, de maintenance simplifiée et de vérification de type stricte.

Un EnumSet sera utilisé lorsque vous aurez besoin d'une variable pour assumer plus d'une valeur Enum à la fois. Par exemple, une police avec laquelle vous écrivez à l'écran peut être à la fois en gras et en en italique en même temps. Un EnumSet vous permettra d’ajouter les différentes valeurs et de vérifier si l’une d’elles est réellement définie à un moment donné. Si vous êtes arrivé à Java à partir d'autres langages de programmation, il s'agit de la fonctionnalité généralement appelée flags.

Comparez les deux:

enum Size { S, M, L, XL, XXL, XXXL }
Size currentSize;
...
currentSize = Size.S;
...
if (currentSize == Size.S) ...

définit, attribue puis recherche une seule valeur Enum.

enum FontStyle { Bold, Italic, Underline, Strikethrough }
EnumSet<FontStyle> currentStyle;
...
currentStyle = EnumSet.of(FontStyle.Bold, FontStyle.Italic);
...
if (currentStyle.contains(FontStyle.Italic)) ...

définit, attribue deux valeurs Enum en même temps, puis vérifie si l’une d’elles est définie ou non.

37
Gábor

Du livre de Joshua Bloch lui-même et dans sa propre Parole:

Le package Java.util fournit la classe EnumSet pour représenter efficacement des ensembles de valeurs tirées d'un seul type enum. Cette classe implémente l’interface Set, fournissant toute la richesse, la sécurité de type et l’interopérabilité que vous obtenez avec toute autre implémentation de Set. Mais en interne, chaque EnumSet est représenté sous forme de vecteur de bits. Si le type enum sous-jacent comporte soixante-quatre éléments ou moins (et la plupart le font), l'ensemble EnumSet est représenté par un seul long; ses performances sont donc comparables à celles d'un champ de bits. Les opérations en bloc, telles que removeAll et rétentionAll, sont implémentées à l'aide de l'arithmétique par bits, comme vous le ferez manuellement pour les champs de bits. Mais vous êtes isolé de la laideur et de la prédisposition aux erreurs du jeu manuel. EnumSet fait le travail difficile pour vous.

Donc, nous pouvons faire quelque chose comme ça.

public class SizeSet {

  public enum Size {S, M, L, XL, XXL, XXXL}

  public void applySize(Set<Size> sizes){}

}

Code client appelant cela pourrait faire quelque chose comme

SizeSet largeSizeSet = new SizeSet();
largeSizeSet.applySize(EnumSet.of(Size.L, Size.XXL, Size.XXL));

Notez que la méthode applySize utilise le Set<Size> Plutôt qu'un EnumSet<Size>. Bien qu'il soit assez évident et probable que le client transmette un EnumSet à la méthode, il est recommandé d'accepter une interface plutôt qu'une implémentation concrète.

12
shashwatZing

EnumSet est spécifiquement utilisé pour stocker l'élément de type enum et pour l'itérer rapidement. Par exemple.

for (Day d : EnumSet.range(Day.MONDAY, Day.FRIDAY))
        System.out.println(d);

L'extrait ci-dessus affiche les jours de la semaine du lundi au vendredi.

7
sambhu

Selon doc Oracle

Les ensembles d'énumération sont représentés de manière interne en tant que vecteurs de bits. Cette représentation est extrêmement compacte et efficace.

Lisible, tapez en toute sécurité, faible empreinte mémoire ... Que voulez-vous de plus?

4
jeton

Étant donné l'exemple suivant:

....
public static final String S = "s";
public static final String M = "m";
public static final String L = "l";
....

Set<String> sizeSet = new HashSet<String>();
sizeSet.add(S);
sizeSet.add(M);

oui, quel est sizeSet ​​dans l'exemple ci-dessus?

EnumSet n'est pas différent de l'exemple ci-dessus, seulement qu'EnumSet est une implémentation Set spéciale qui fonctionne avec et optimise avec les types enum, c'est tout.

3
Adrian Shum
EnumSet largeSize

EnumSet largeSize est un ensemble de valeurs Enum qui contient XL, XXL et XXXL.

Size 

La taille est une classe de type Enum avec les valeurs constantes S, M, L, XL, XXL, XXXL.

largeSize.iterator()

L'Iterator for EnumSet est dans l'ordre naturel, l'ordre dans lequel les valeurs de l'énum ont été déclarées à l'origine.

  • La classe EnumSet est membre de la structure de collections Java & n'est pas synchronisée.
  • C’est une implémentation haute performance, ils sont beaucoup plus rapides que HashSet.
  • Tous les éléments de chaque instance EnumSet doivent être des éléments d'un seul type enum.

Pour en savoir plus, lisez le document api: http://docs.Oracle.com/javase/8/docs/api/Java/util/EnumSet.html

3
Sarwesh Sethiya

En règle générale, EnumSet devrait toujours être préféré à toute autre implémentation de Set lorsque nous stockons des valeurs enum.

Avantages de l'utilisation d'un EnumSet:

Les méthodes d'un EnumSet sont implémentées à l'aide d'opérations arithmétiques au niveau des bits. Ces calculs étant très rapides, toutes les opérations de base sont exécutées dans un temps constant.

Si nous comparons EnumSet avec d'autres implémentations de Set comme HashSet, la première solution est généralement plus rapide, car les valeurs sont stockées dans un ordre prévisible et un seul bit doit être examiné pour chaque calcul. Contrairement à HashSet, il n’est pas nécessaire de calculer le hashcode pour trouver le bon compartiment.

De plus, en raison de la nature des vecteurs bits, un EnumSet est très compact et efficace. Par conséquent, il utilise moins de mémoire, avec tous les avantages qu'il apporte.

les règles sonarsource disent :

Lorsque tous les éléments d'un ensemble sont des valeurs de la même énumération, cet ensemble peut être remplacé par un EnumSet, ce qui peut s'avérer beaucoup plus efficace que d'autres ensembles, car la structure de données sous-jacente est un bitmap simple.

EnumMap

La source est ici

0
yoAlex5

Un EnumSet est une collection spécialisée permettant de travailler avec des classes enum. Il implémente l'interface Set et s'étend de AbstractSet:

enter image description here

Lorsque vous envisagez d’utiliser un EnumSet, vous devez tenir compte de certains points:

  1. Il ne peut contenir que des valeurs enum et toutes les valeurs doivent appartenir à la même enum
  2. Il n’est pas permis d’ajouter des valeurs NULL, en lançant une NullPointerException pour tenter de le faire
  3. Il n’est pas thread-safe, nous devons donc le synchroniser en externe si nécessaire
  4. Les éléments sont stockés dans l'ordre dans lequel ils sont déclarés dans l'énumération.
  5. Il utilise un itérateur de sécurité qui fonctionne sur une copie. Il ne lève donc pas d’exception ConcurrentModificationException si la collection est modifiée lors de son itération.

Maintenant le EnumSet largeSize partie est une déclaration de variable , donc oui, elle est de type EnumSet. Veuillez noter que vous pouvez ajouter le type d'éléments dans la collection pour une meilleure sécurité du type: EnumSet<Size>

Consultez cet article pour en savoir plus sur EnumSet .

0
Johnny