从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)枚举集应该是可行的-您可以从一个枚举中获取所有值。++,但实际上,您不应该使用序数。设置一个内部索引系统