Подтвердить что ты не робот

Что означает EnumSet?

У меня есть следующий пример:

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;

}

В этом коде я могу понять, что Enum создает тип размеров Enum.

Мой вопрос: есть largeSize объект типа EnumSet? Что это на самом деле значит? Я действительно хочу понять это лучше.

4b9b3361

Ответ 1

Что касается любой переменной, ее тип найден в ее объявлении:

EnumSet largeSize

Итак, да, largeSize (который должен быть назван largeSizes поскольку он является коллекцией) имеет тип EnumSet. Он также должен быть обобщен и, таким образом, объявлен как

EnumSet<Size> largeSizes

Это означает, что largeSizes имеет тип EnumSet. EnumSet - это Set который содержит экземпляр enum определенного типа перечисления более эффективным способом, чем другие реализации Set (например, HashSet, TreeSet и т.д.). Чтобы узнать, что такое EnumSet, прочитайте его API.

Ответ 2

Упрощение кода

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

Вы можете видеть, что largeSize является обычным Set, за исключением того, что он предназначен для хранения Enums. Как все иначе? Во-первых, JVM знает все возможные значения набора, что означает вместо хранения всех объектов, которые он может использовать растровое изображение, где 1 означает, что элемент присутствует, а 0 означает, что это не так. Это также означает, что порядок множества - это порядок порядковых значений, то есть порядок, который они определяли. Вот почему это печатает

L XL XXL XXXL

Если вы хотите узнать более подробно, я предлагаю вам прочитать источник этого класса.

Ответ 3

Простой Enum - это список значений, которые вы можете выбрать только один раз за раз. Используя ваш пример, размер может быть только одним из S, M, L и т.д. Для любой ткани. Вы можете использовать простые константы вместо Enum, но это имеет свои преимущества читаемости, упрощения обслуживания и строгой проверки типов.

An EnumSet будет использоваться, когда вам потребуется переменная, чтобы принять более одного значения Enum в одно и то же время. Например, шрифт, который вы пишете на экране, может быть одновременно полужирным и курсивом. EnumSet позволит вам добавить различные значения и проверить, действительно ли один из них установлен в любой момент времени. Если вы пришли на Java с других языков программирования, это функциональность, обычно называемая flags.

Сравните два:

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

определяет, назначает и затем проверяет одно значение Enum.

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

определяет, присваивает два значения Enum в одно и то же время, а затем проверяет, действительно ли установлено одно из них.

Ответ 4

Из Джошуа Блоха книга сама и своим словом:

Пакет java.util предоставляет класс EnumSet для эффективного представления наборов значений, взятых из одного типа перечислений. Этот класс реализует интерфейс Set, обеспечивающий все богатство, тип безопасности и интероперабельность, которую вы получаете с любой другой реализацией Set. Но внутренне каждый EnumSet представлен как бит-вектор. Если базовый тип перечисления имеет шестьдесят четыре или меньше элементов - и большинство из них - весь EnumSet представлен одним длинным, поэтому его производительность сопоставима с характеристикой битового поля. Массовые операции, такие как removeAll и keepAll, реализованы с использованием бит-мудрых арифметика, так же, как вы будете делать вручную для полей бит. Но ты изолированный от уродства и погрешности при использовании ручного бита вертел. EnumSet делает для вас тяжелую работу.

Итак, мы можем сделать что-то вроде этого.

public class SizeSet {

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

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

}

Клиентский код, вызывающий его, может сделать что-то вроде

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

Обратите внимание, что метод applySize принимает Set<Size>, а не EnumSet<Size>. Хотя это довольно очевидно, и вероятность того, что клиент передаст EnumSet этому методу, является хорошей практикой принимать интерфейс, а не конкретную реализацию.

Ответ 5

EnumSet специально используется для хранения элемента типа enum и его быстрого повторения. Например.

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

В приведенном выше фрагменте будут отображаться дни недели с понедельника по пятницу.

Ответ 6

Согласно Oracle doc

Множества Enum представлены внутри как битовые векторы. Это представление чрезвычайно компактно и эффективно.

Считываемый, безопасный тип, низкий объем памяти... Что вам нужно больше?

Ответ 7

В следующем примере:

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

Итак, что такое sizeSet ​​в приведенном выше примере?

EnumSet ничем не отличается от приведенного выше примера, только EnumSet - это специальная реализация Set, которая работает и оптимизируется с типами перечислений, что все.

Ответ 8

EnumSet largeSize

EnumSet largeSize - это набор значений Enum, содержащий XL, XXL и XXXL.

Size 

Размер - это класс типа Enum с постоянными значениями S, M, L, XL, XXL, XXXL.

largeSize.iterator()

Итератор для EnumSet находится в естественном порядке, порядок, в котором первоначально были объявлены значения перечисления.

  • Класс EnumSet является членом структуры коллекций Java и не синхронизирован.
  • Его реализация с высокой производительностью, они намного быстрее, чем HashSet.
  • Все элементы каждого экземпляра EnumSet должны быть элементами одиночный тип перечисления.

Чтобы узнать больше, прочитайте api doc: http://docs.oracle.com/javase/8/docs/api/java/util/EnumSet.html

Ответ 9

EnumSet - это специализированная коллекция Set для работы с enum-классами. Он реализует интерфейс Set и расширяется от AbstractSet:

enter image description here

Когда вы планируете использовать EnumSet, вы должны принять во внимание некоторые моменты:

  1. Он может содержать только значения перечисления, и все значения должны принадлежать одному и тому же перечислению
  2. Это не позволяет добавлять нулевые значения, выбрасывая NullPointerException в попытке сделать это
  3. Это не потокобезопасно, поэтому мы должны синхронизировать его внешне, если требуется
  4. Элементы хранятся в том порядке, в котором они объявлены в перечислении
  5. Он использует отказоустойчивый итератор, который работает с копией, поэтому он не будет генерировать исключение ConcurrentModificationException, если коллекция изменяется при итерации по ней.

Теперь, часть EnumSet largeSize является объявлением переменной, так что да, это тип EnumSet. Обратите внимание, что вы можете добавить тип элементов в коллекцию для большей безопасности типов: EnumSet<Size>

Проверьте эту статью, чтобы узнать больше о EnumSet.

Ответ 10

Как правило, EnumSet всегда предпочтительнее любой другой реализации Set, когда мы храним значения enum.

Преимущества использования EnumSet:

Методы в EnumSet реализованы с использованием арифметических побитовых операций. Эти вычисления очень быстрые, и поэтому все основные операции выполняются за постоянное время.

Если мы сравним EnumSet с другими реализациями Set, такими как HashSet, первое обычно быстрее, потому что значения хранятся в предсказуемом порядке, и для каждого вычисления необходимо проверять только один бит. В отличие от HashSet, нет необходимости вычислять хеш-код, чтобы найти правильный сегмент.

Более того, из-за природы битовых векторов, EnumSet очень компактен и эффективен. Поэтому он использует меньше памяти со всеми вытекающими отсюда преимуществами.

Правила сонарсорса говорят:

Когда все элементы в наборе являются значениями из одного и того же перечисления, набор может быть заменен набором EnumSet, который может быть намного более эффективным, чем другие наборы, поскольку базовая структура данных представляет собой простое растровое изображение.

EnumMap

Источник здесь

Ответ 11

Он быстро превращает все элементы Enum в набор, EnumSet - это еще один тип Set.

public enum Style { BOLD, ITALIC, UNDERLINE, STRIKETHROUGH }

EnumSet.of(Style.BOLD, Style.ITALIC);