我处于两种实现方式之间的两难境地,并且想知道哪些方法更有效(内存和\或时间方面)。
我需要获取包含操作码的请求,并将其映射到类别。有1000到2000个操作码只有3-4个类别。 映射是预定义且众所周知的。
解决方案1:
使用HashMap<Integer, Category>
它很简单,但我认为它浪费了太多的内存,因为它的映射很多。
解决方案2: 预先定义一个Enumartion:
public enum CategoryEum{
C1("123", "456",....),
C2("777","888",...)
... }
然后将此枚举用于:
EnumMap<CategoryEnum, Category>
我读到EnumMap紧凑而高效。
重要提示:两种解决方案中的地图都会启动一次,并且在整个生命周期内都不会发生变化。
您怎么看?
答案 0 :(得分:3)
如果您的操作码是0到2000之间的连续整数,则不需要地图。使用op-codes作为数组的索引,就像这样(注意硬编码只是为了简洁起见):
Category[] mapping = {
Category.A, // Opcode 0
Category.A, // Opcode 1
Category.B, // Opcode 2
...
};
int opcode = ...
Category category = mapping[opcode];
如果您的操作码不是连续且稀疏的(有大的间隙),您的枚举解决方案可能会起作用,因为您可以将操作码编码为枚举并使用枚举序数作为数组索引:
Category[] mapping = {
Category.A, // Opcode 13 (the first possible opcode)
Category.A, // Opcode 42 (the second possible opcode)
Category.B, // Opcode 88 (the third possible opcode)
...
};
int opcode = opcodeEnum.ordinal();
Category category = mapping[opcode];
请注意,在后一种情况下,EnumMap
与上述解决方案完全相同,尽管占用了更多内存,因为它包含Map.entrySet()
和其他调用的一些缓存。
HashMap
在任何情况下,如果您在可能的操作码空间中为每个操作码提供一个类别,那么阵列或EnumMap
解决方案应优先于HashMap
解决方案。如果您只对1%的操作码进行分类,那么为整个操作码空间创建数组会浪费太多内存,而HashMap
可能会更好。
答案 1 :(得分:1)
解决方案1:使用
HashMap<Integer, Category>
这很简单,但我认为它浪费了太多内存,因为它的映射很多。
实际上,它可能不超过10-20KB,这几天几乎没有碎屑。 HashMap
只是一个指针数组。
但是,如果您一直将int
转换为Integer
,那可能不是世界上最好的。
EnumMap<CategoryEnum, Category>
我认为这实际上不会帮助你,因为现在你需要将操作码映射到CategoryEnum
。
如果操作码的数值不是很大(几千),那么到目前为止最好的选择就是使用Category[]
并将操作码直接索引到数组中。数组的长度必须是最高操作码+1的值。
如果数值超过几千,那么 (DIY有点像Java异端邪说,但是在他们给我们原始的泛型之前我们就被卡住了。)
还有一些图书馆也有原始馆藏。