有没有一种方法可以有效地在Java中存储枚举值序列?

有没有一种方法可以有效地在Java中存储枚举值序列?,java,collections,enums,Java,Collections,Enums,我正在寻找一种在Java中编码枚举值序列的方法,这种方法可以更好地为每个元素打包一个对象引用。在幻想代码中: List<MyEnum> list = new EnumList<MyEnum>(MyEnum.class); 原则上,应该可以使用每个元素的log2MyEnum.values.length位对每个元素进行编码。是否有一个现有的实现,或者一个简单的方法来实现它 拥有一个编码任意基数的数字序列的类就足够了,即,如果有5个可能的枚举值,则将基数5用于字节序列,因为可

我正在寻找一种在Java中编码枚举值序列的方法,这种方法可以更好地为每个元素打包一个对象引用。在幻想代码中:

List<MyEnum> list = new EnumList<MyEnum>(MyEnum.class);
原则上,应该可以使用每个元素的log2MyEnum.values.length位对每个元素进行编码。是否有一个现有的实现,或者一个简单的方法来实现它

拥有一个编码任意基数的数字序列的类就足够了,即,如果有5个可能的枚举值,则将基数5用于字节序列,因为可以使用一个简单的包装类来实现列表

我更喜欢一个通用的、现有的解决方案,但作为穷人的解决方案,我可能只使用一个long数组,并将尽可能多的元素编码到每个long中。对于5个枚举值,27个元素可以放入一个长的数组中,并且只浪费~1.3位,这非常好


注意:我不是在寻找一个集合实现。这不会保留序列。

您可以将位存储在int 32位、32个开关中。但是除了锻炼的价值外,还有什么意义?-你说的是非常小的记忆量。更好的问题可能是,为什么要在枚举引用中保存一些字节?程序的其他部分可能会占用更多内存


如果你关心高效地传输数据,你可以考虑单独使用枚举,但是使用自定义序列化,但是同样,这将是一个值得付出努力的不寻常的情况。

< P>你可以在int 32位,32个开关中存储位。但是除了锻炼的价值外,还有什么意义?-你说的是非常小的记忆量。更好的问题可能是,为什么要在枚举引用中保存一些字节?程序的其他部分可能会占用更多内存


如果你关心高效地传输数据,你可以考虑单独使用枚举,但是使用自定义序列化,但同样,这将是一个值得付出努力的不寻常的情况。

< P>一个对象引用通常占据一个32位或64位字。要做得更好,您需要将枚举值转换为小于32位的数字,并将它们保存在一个数组中

转换为数字就像调用getOrdinal一样简单。从那里你可以:

强制转换为字节或短,然后将序列表示为字节/短值数组,或 对int值数组使用合适的压缩算法。 当然,所有这些都是以使代码更加复杂为代价的。例如,您不能使用集合API,您必须自己进行序列管理。我怀疑这是否值得,除非你必须处理非常大的序列或大量的序列

原则上,应该可以使用log2MyEnum.values.length位对每个元素进行编码


事实上,你可以做得更好。。。通过压缩序列。它取决于有多少冗余。

一个对象引用通常占用一个32位或64位字。要做得更好,您需要将枚举值转换为小于32位的数字,并将它们保存在一个数组中

转换为数字就像调用getOrdinal一样简单。从那里你可以:

强制转换为字节或短,然后将序列表示为字节/短值数组,或 对int值数组使用合适的压缩算法。 当然,所有这些都是以使代码更加复杂为代价的。例如,您不能使用集合API,您必须自己进行序列管理。我怀疑这是否值得,除非你必须处理非常大的序列或大量的序列

原则上,应该可以使用log2MyEnum.values.length位对每个元素进行编码


事实上,你可以做得更好。。。通过压缩序列。这取决于有多少冗余。

我认为这对于内存中的元素来说是不容易做到的,除了作为未绑定的原语处理之外——甚至不能使用标准的泛型集合。现在,如果谈论比特流序列化格式,如果您需要在这个级别上提高空间效率,那么Java不是合适的语言。你可以考虑一个JNI扩展来完成这样的事情。我以前从未听说过。是的,有一个将任意基数的数字序列编码成字节序列的类可以解决这个问题,但我不知道有这样的类。我最好的猜测是利用BigInteger并处理性能损失。@Sam See ByteBuffers,fwiw,尽管看起来工作量太大了。。这真的会使程序成功/失败吗?ByteBuffer会将内存使用量降低到每个元素1字节,但不能低于1字节。为了做得更好,例如使用5个枚举值,您可以将3个元素编码为1个
te使用基数5:elem1.ordinal+5*elem2.ordinal+25*elem3.ordinal,总共125个可能的值。这更好,但有没有一个通用的解决方案不浪费最后的1+位并推广到任意基数?我认为这对于内存中的元素来说是不容易做到的,除了将其视为未绑定的原语之外——甚至不能使用标准的泛型集合。现在,如果谈论比特流序列化格式,如果您需要在这个级别上提高空间效率,那么Java不是合适的语言。你可以考虑一个JNI扩展来完成这样的事情。我以前从未听说过。是的,有一个将任意基数的数字序列编码成字节序列的类可以解决这个问题,但我不知道有这样的类。我最好的猜测是利用BigInteger并处理性能损失。@Sam See ByteBuffers,fwiw,尽管看起来工作量太大了。。这真的会使程序成功/失败吗?ByteBuffer会将内存使用量降低到每个元素1字节,但不能低于1字节。为了做得更好,例如使用5个枚举值,您可以使用基数5:elem1.ordinal+5*elem2.ordinal+25*elem3.ordinal将3个元素编码为1个字节,总共有125个可能的值。这更好,但是有没有一个通用的解决方案不浪费最后的1+位并推广到任意基数?我计划存储大量的枚举字符串,因此内存使用量很大。枚举类型有多少个值?我仍然怀疑这是否值得。我计划存储大量枚举字符串,因此内存使用量很大。枚举类型有多少个值?我仍然怀疑这是否值得。