1

我正在寻找一种方法来编码 Java 中的枚举值序列,它比每个元素的一个对象引用更好。在幻想代码中:

List<MyEnum> list = new EnumList<MyEnum>(MyEnum.class);

原则上应该可以使用每个元素的比特来编码每个元素。是否有一个现有的实现,或者一个简单的方法来做到这一点?log2(MyEnum.values().length)

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

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

注意:我不是在寻找一套实现。那不会保留序列。

4

2 回答 2

2

您可以将位存储在 int 中(32 位,32 个“开关”)。但是除了锻炼价值之外,还有什么意义呢?-您实际上是在谈论非常少量的内存。一个更好的问题可能是,为什么要在枚举引用中保存几个字节?程序的其他部分可能会使用更多的内存。

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

于 2012-11-10T03:14:30.837 回答
2

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

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

  • 强制转换为byteor short,然后将序列表示为字节/短值数组,或
  • int值数组使用合适的压缩算法。

当然,所有这些都是以使您的代码更加复杂为代价的。例如,您不能使用集合 API,您必须自己进行序列管理。我怀疑这是否值得,除非您必须处理非常大的序列或大量的序列。


原则上应该可以使用log2(MyEnum.values().length)比特对每个元素进行编码。

实际上,您可能会做得比这更好……通过压缩序列。这取决于有多少冗余。

于 2012-11-10T03:17:32.627 回答