有没有办法在Java中有效地存储一系列枚举值?

时间:2012-11-10 03:08:07

标签: java collections enums

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

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

原则上应该可以使用每个元素log2(MyEnum.values().length)位对每个元素进行编码。是否有现成的实现,或者是一种简单的方法吗?

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

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

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

2 个答案:

答案 0 :(得分:2)

您可以将位存储在int(32位,32“开关”)中。但除了运动价值之外,重点是什么? - 你真的在谈论的是非常少量的记忆。一个更好的问题可能是,为什么要在枚举引用中保存几个字节?程序的其他部分可能会占用更多内存。

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

答案 1 :(得分:2)

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

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

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

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


  

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

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