2012-08-17 60 views
14

一些Message类是能够返回标签名基于标签号码

因为此类实例化以后,很多时候,我有点舍不得为每个实例创建一个HashMap:Java的硬编码开关VS HashMap的

public class Message { 
    private HashMap<Integer,String> tagMap; 

    public Message() { 
    this.tagMap = new HashMap<Integer,String>(); 
    this.tagMap.put(1, "tag1Name"); 
    this.tagMap.put(2, "tag2Name"); 
    this.tagMap.put(3, "tag3Name"); 
    } 

    public String getTagName(int tagNumber) { 
    return this.tagMap.get(tagNumber); 
    } 
} 

赞成硬编码的:

public class Message { 
    public Message() { 
    } 

    public String getTagName(int tagNumber) { 
    switch(tagNumber) { 
     case 1: return "tag1Name"; 
     case 2: return "tag2Name"; 
     case 3: return "tag3Name"; 
     default return null; 
    } 
    } 
} 

当你把一切都在混合(内存,性能,GC,...)

是否有理由坚持HashMap?

+2

难道这不是'枚举'会是理想的情况吗? – Edd 2012-08-17 09:48:32

+5

如果列表对于所有消息都是相同的,那么也可以使地图变为静态。 – assylias 2012-08-17 09:49:52

+1

另外,你是否(通过剖析)确定该类的实例化确实是一个问题? – joergl 2012-08-17 09:51:00

回答

6

在静态块中初始化MAP

而且因为你将要创建Message.you的许多对象应该这样写代码

public class Message { 

    private static HashMap tagMap; 

    static { 
    tagMap = new HashMap(); 
    tagMap.put(1, "tag1Name"); 
    tagMap.put(2, "tag2Name"); 
    tagMap.put(3, "tag3Name"); 
    } 

    public Message() { 

    } 

    public String getTagName(int tagNumber) { 
    return tagMap.get(tagNumber); 
    } 
} 
+0

我不知道如何在静态块中调用put()。 Sweet – MonoThreaded 2012-08-17 09:58:44

+0

使用Map不能比使用开关更快,这没有任何意义。 – barjak 2012-08-17 10:00:38

+0

@Byter是否有任何证据表明Map(以及Map的实现)比交换机更快?你真的测试过这个吗? – Eugene 2012-08-17 10:01:52

0

取决于你需要什么。例如,如果您需要使用Map来获取所有显示的标签名称,那么这个名称就可以获得回报。此外,如果您替换为TreeMap,则可以对它们进行排序。
如果您没有这种需求,那么使用Map将会是一种开销,您的方法或Enum会更有效率(尽管比您选择5-10-20 case选项的可读性要低)

0

为什么不从属性的getTagName方法静态和懒加载文件?

public static String getTagName(int tagNumber) { 
    if tagsByID == null) { 
     // load tags from properties 
    } 
    return tagsByID.get(tagNumber); 
} 

易于测试和配置,无需重新编译。

+0

属性文件意味着额外的可交付成果。由于列表相当静态,我宁愿嵌入映射。 – MonoThreaded 2012-08-17 10:02:41

0

如果所有标记值在区间[1..n]中连续,则可以使用数组或可以使用ArrayList,并且可以直接访问这些值。

public class Message { 
    private ArrayList<String> tags; 

    public Message() { 
     this.tags = = new ArrayList<String>(); 
     this.tags.add("Unknown"); 
     this.tags.add("tag1Name"); 
     this.tags.add("tag2Name"); 
     this.tags.add("tag3Name"); 
    } 

    public String getTagName(int tagNumber) { 
     return this.tags.get(tagNumber); 
    } 
} 

用数组替代。

public class Message { 
    private static final String[] tags = { 
     "N/A", 
     "tag1Name", 
     "tag2Name", 
     "tag3Name", 
     null, 
     null, 
     "tag6Name", 
    }; 

    public Message() { 
    } 


    public String getTagName(int tagNumber) { 
     if (tagNumber < 0 || tagNumber > tags.length) { 
      throw new IllegalArgumentException(); 
     return tags[tagNumber]; 
    } 
} 
+0

不幸的是它不是一个连续的列表 – MonoThreaded 2012-08-17 09:59:21

+0

@AknownImous太糟糕了。但我会让我的答案依然存在。 – maba 2012-08-17 10:00:57

+0

@AknownImous你有什么想法如何标签编号?也许你可以在数组中留出一些空白,而不会占用太多内存。 – maba 2012-08-17 10:12:16

1

地图可以被用作其中键代表条件和值表示要执行的命令的唯一缺点是对象被创建之前使用,因此如果有大量的这样的条件,那么你可以选择地图命令模式否则switch总是优雅的方法,如果你的条件很少。