HashMap与EnumMap场景

时间:2016-03-10 22:38:04

标签: java

我处于两种实现方式之间的两难境地,并且想知道哪些方法更有效(内存和\或时间方面)。

我需要获取包含操作码的请求,并将其映射到类别。有1000到2000个操作码只有3-4个类别。 映射是预定义且众所周知的。

解决方案1: 使用HashMap<Integer, Category> 它很简单,但我认为它浪费了太多的内存,因为它的映射很多。

解决方案2: 预先定义一个Enumartion:

public enum CategoryEum{
C1("123", "456",....),
C2("777","888",...) 
... }

然后将此枚举用于:

EnumMap<CategoryEnum, Category>

我读到EnumMap紧凑而高效。

重要提示:两种解决方案中的地图都会启动一次,并且在整个生命周期内都不会发生变化。

您怎么看?

2 个答案:

答案 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异端邪说,但是在他们给我们原始的泛型之前我们就被卡住了。)

还有一些图书馆也有原始馆藏。