Получение значения из EnumSet в Java - PullRequest
6 голосов
/ 12 декабря 2008

Если вы используете EnumSet для хранения обычных двоичных значений (1,2,4 и т. Д.), То при наличии менее 64 элементов я считаю, что это сохраняется в виде битового вектора и представляется эффективно как долго. Есть ли простой способ получить значение этого длинного. Я хочу быстрый и простой способ сохранить содержимое набора в файл или базу данных.

Если бы я делал это по-старому, я бы просто использовал long и делал все немного, несмотря на все проблемы безопасности типов и т. Д.

Ответы [ 7 ]

6 голосов
/ 12 декабря 2008

Насколько я знаю, это не разоблачено. Вы могли бы переписать его самостоятельно - взгляните на код EnumSet, чтобы получить представление о коде - но жаль, что нет лучшего способа получить его: (

5 голосов
/ 12 декабря 2008

Я не думаю, что это можно сделать общим способом. Преобразовать в длинную довольно легко:

public static <T extends Enum<T>> long enumSetToLong(EnumSet<T> set)
{
    long r = 0;
    for(T value : set)
    {
        r |= 1L << value.ordinal();
    }
    return r;
}

Я не знаю, как вы вообще можете конвертировать из длинного спина в EnumSet. Я не знаю способа (если не считать отражения) получить массив значений перечисления для поиска. Вам придется делать это на основе перечисления.

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

2 голосов
/ 26 апреля 2014

Как упоминал Джон Скит, эта информация не раскрывается. Но Дейв Рэй показал, как это легко вычислить. Я сделал библиотеку, которая делает такие преобразования намного проще. Он также проверяет, что на самом деле не более 64 элементов, если вы используете «long». Мне пришлось создать новый тип данных, но он может быть использован как BitSet или EnumSet. Обратите внимание, что для этого требуется Java 8 или новее, поскольку для этого используются интерфейсы с реализациями по умолчанию.

Вот ссылка: http://claude -martin.ch / enumbitset /

Пример:

  static enum MyEnum implements EnumBitSetHelper<MyEnum> { A, B, C }
  public static void main(final String[] args) {
    final EnumBitSet<MyEnum> set = EnumBitSet.of(MyEnum.A, MyEnum.C);
    long bitmask = set.toLong(); // = 3
  }
1 голос
/ 12 августа 2014

если добавление параметра с классом перечисления возможно. пример, который преобразует enumset в байт:

public static <T extends Enum<T>, U extends Enum<?>> byte toByte(EnumSet<T> set, Class<U> type) {
  byte b = 0;

  if(type.getEnumConstants().length > 8) {
    throw new RuntimeException("enum set doesn't fit in one byte");
  }

  for(Enum<?> e: type.getEnumConstants()) {
    if(set.contains(e)) {
      b |= 1 << e.ordinal();
    }
  }

  return b;
}

public static <E extends Enum<E>> EnumSet<E> toSet(byte b, Class<E> type) {
  E[] enums = type.getEnumConstants();
  EnumSet<E> enumSet = EnumSet.noneOf(type);

  for(int bit = 0; bit < 8; bit++) {
    if((b & 1 << bit) > 0) {
      enumSet.add(enums[bit]);
    }
  }

  return enumSet;
}
1 голос
/ 12 декабря 2008

EnumSet реализует Serializable, так что вы можете просто написать это с ObjectOutputStream.

0 голосов
/ 16 декабря 2013

BitSet может быть полезно в этой ситуации, поскольку обеспечивает преобразование в / из массива байтов. Вам все еще может потребоваться объявить enum с явными значениями (1,2,3 ..) для BitSet индеек. В отличие от long, который всегда 64-битный, BitSet не позволяет ограничить его длину (например, до 64 бит).

0 голосов
/ 14 декабря 2008

(Типичная - не обязательная) реализация EnumSet использует порядковые номера значений enum. Вы не должны предполагать, что порядковые номера всегда будут такими же. Поэтому, если вы хотите эффективно хранить наборы перечислений с использованием порядковых номеров, вам следует также сохранить карту от имени перечисления до порядкового номера (вероятно, сохраненную как последовательность имен перечисления).

Сам EnumSet, похоже, не имеет отличной сериализованной формы. Это просто выбрасывает перечисления. Тело которого будет транскрибировано в серию целочисленных ссылок на объекты, а не в набор битов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...