Что означает 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? Что это на самом деле значит? Я действительно хочу понять это лучше.
Ответы
Ответ 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, вы должны принять во внимание некоторые моменты:
- Он может содержать только значения перечисления, и все значения должны принадлежать одному и тому же перечислению
- Это не позволяет добавлять нулевые значения, выбрасывая NullPointerException в попытке сделать это
- Это не потокобезопасно, поэтому мы должны синхронизировать его внешне, если требуется
- Элементы хранятся в том порядке, в котором они объявлены в перечислении
- Он использует отказоустойчивый итератор, который работает с копией, поэтому он не будет генерировать исключение 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);