从Java中的枚举集获取值

从Java中的枚举集获取值,java,Java,如果使用EnumSet存储传统的二进制值(1、2、4等),那么当少于64个项时,我会认为这是存储为位向量,并有效地表示为长。有没有一个简单的方法来获得这个长的值。我想要一种快速简单的方法将集合的内容存储在文件或数据库中 如果我是用老方法做这件事的话,我只会用一个长的,我自己做一点小动作,尽管有所有的类型安全等问题。实现了可序列化的,所以你可以用ObjectOutputStream写出来,据我所知,这是没有公开的。基本上,您可以自己重写它-查看EnumSet的代码以了解代码-但遗憾的是,没有更好的

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


如果我是用老方法做这件事的话,我只会用一个长的,我自己做一点小动作,尽管有所有的类型安全等问题。

实现了
可序列化的
,所以你可以用
ObjectOutputStream
写出来,据我所知,这是没有公开的。基本上,您可以自己重写它-查看EnumSet的代码以了解代码-但遗憾的是,没有更好的方法可以做到这一点:(

我认为这不能用通用的方法完成。转换为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;
}
公共静态长enumSetToLong(EnumSet)
{
长r=0;
用于(T值:设置)
{
r |=1L枚举集的(典型-不强制)实现使用枚举值的序号。您不应该假设序号始终保持不变。因此,如果您想使用序号高效地存储枚举集,还应该存储从枚举名到序号的映射(可能存储为枚举名序列)


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

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

如Jon Skeet所述,此信息没有公开。但Dave Ray演示了如何轻松计算它。 我制作了一个库,使这种转换变得简单得多。如果使用“long”,它还会检查是否确实不超过64个元素。我必须创建一个新的数据类型,但它可以像位集或枚举集一样使用。请注意,这需要Java 8或更高版本,因为它使用带有默认实现的接口

以下是链接:

例如:

  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
  }
静态enum MyEnum实现EnumBitSetHelper{A,B,C}
公共静态void main(最终字符串[]args){
final EnumBitSet=EnumBitSet.of(MyEnum.A,MyEnum.C);
长位掩码=set.toLong();//=3
}

如果在枚举类中添加参数,则是可能的。将枚举集转换为字节的示例如下:

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

public static Reflection暗魔法可用于检索值,但这既不是“快速”也不是“简单”。枚举集实际上是抽象的,因此情况会更糟。您确实应该检查序数是否小于64.long(+Class)枚举集应该是可行的-您可以从一个枚举中获取所有值。++,但实际上,您不应该使用序数。设置一个内部索引系统