Что означает 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;

}

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

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

9 55

9 ответов:

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

EnumSet largeSize

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

EnumSet<Size> largeSizes

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

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

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

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

L XL XXL XXXL

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

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

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

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

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 значения в то же время, затем проверяет, является ли один из них на самом деле набор или нет.

из самой книги Джошуа Блоха и его собственным словом:

java.пакет util предоставляет класс EnumSet для эффективного представления наборы значений, полученные из одного типа перечисления. Этот класс реализует установленный интерфейс, обеспечивающ все богатство, тип безопасность и совместимость вы получаете с любой другой реализацией набора. Но внутренне каждый набор перечислений представлен в виде битового вектора. Если базовый тип перечисления имеет шестьдесят четыре или меньше элементов - и большинство делать -- весь EnumSet представлен одним длинным, поэтому его производительность сопоставима с производительностью битового поля. Групповая операция, такие как removeAll и retainAll, реализуются с использованием битовой мудрости арифметика, как вы будете делать вручную для битовых полей. Но это так. изолированный от уродства и ошибок-склонность ручного бит вертимому. 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 методу, рекомендуется принять интерфейс, а не конкретную реализацию.

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

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

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

приводит следующий пример:

....
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-это специальная реализация набора, которая работает и оптимизирована с типами перечислений, вот и все.

EnumSet largeSize

EnumSet largeSize-это набор значений перечисления, который содержит XL, XXL и XXXL.

Size 

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

largeSize.iterator()

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

  • класс EnumSet является членом Java Collections Framework и не синхронизирован.
  • свой набор высокой эффективности реализация, они намного быстрее, чем Для поиска HashSet.
  • все элементы каждого экземпляра EnumSet должны быть элементами a один тип перечисления.

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

по данным Oracle doc

перечисления представлены внутренне в виде битовых векторов. Это представление весьма компактно и эффективно.

читаемый, тип безопасный, низкий объем памяти... Чего ты еще хочешь?

он быстро превращает любые элементы перечисления в набор, EnumSet-это еще один тип набора.

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

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