从Java中获取EnumSet的值

时间:2008-12-12 17:42:41

标签: java

如果使用EnumSet存储常规二进制值(1,2,4等),那么当少于64个项目时,我会认为这是存储为位向量并且是有效地表示为长期。有没有一种简单的方法来获得这个长期的价值。我想要一种快速简单的方法将集合的内容存储在文件或数据库中。

如果我以旧方式这样做,我只会使用很长时间,尽管存在所有类型安全等问题,我还是会自己做点什么。

7 个答案:

答案 0 :(得分:6)

据我所知,这并未曝光。您基本上可以自己重写它 - 看看EnumSet的代码以了解代码 - 但遗憾的是没有更好的方法来获取代码:(

答案 1 :(得分:5)

我不认为这可以通用方式完成。转换为long非常简单:

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。我知道没有办法(缺少反射)来获取枚举的values数组来进行查找。你必须在每个枚举的基础上这样做。

我认为序列化是要走的路。只需将序列化作为长整数就更容易受到版本错误的影响,或者重新排列枚举中的常量所导致的错误。

答案 2 :(得分:2)

如Jon Skeet所述,此信息未公开。但Dave Ray展示了如何轻松计算它。 我创建了一个库,使这种转换变得更加简单。如果使用&#34; long&#34;它还会检查实际上不超过64个元素。我不得不创建一个新的数据类型,但它可以像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
  }

答案 3 :(得分:1)

EnumSet实施Serializable,因此您可以使用ObjectOutputStream将其写出来。

答案 4 :(得分:1)

如果使用枚举类添加参数,则可以。将enumset转换为byte的示例:

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;
}

答案 5 :(得分:0)

EnumSet的(典型 - 它没有强制要求)实现使用枚举值'序数。你不应该认为序数总是保持不变。因此,如果您想使用序数有效地存储枚举集,您还应该将枚举名称中的映射存储到序数(可能存储为枚举名称序列)。

EnumSet本身似乎没有很好的序列化形式。它只是抛弃了一个枚举。其主体将被转录为一系列整数对象引用而不是位集。

答案 6 :(得分:0)

BitSet可能在这种情况下很有用,因为它提供了对字节数组的转换。您可能仍需要为enum个indeces声明一个BitSet的显式值(1,2,3 ..)。与long(总是64位)不同,BitSet似乎不允许限制其长度(例如64位)。