HashMap <String,String>是否应该重构为Enum?

问题描述

我有一个映射,该映射表示prefixName和数据库中定义的每个序列的序列名称间的键名(组ID前缀)映射。例如,如果groupId为“ GRP-MMM-PNL”,则应获取该组的相应序列名称“ mmm_panel_group_id”。我的问题是我应该使用Enum而不是定义此HashMap。

@AllArgsConstructor
public enum SequenceName {

    mmm_panel_group_id("GRP-MMM-PNL-"),mmm_service_group_id("GRP-MMM-SRV-"),cms_panel_group_id("GRP-CMS-PNL-"),cms_service_group_id("GRP-CMS-SRV-"),smm_panel_group_id("GRP-SMM-PNL-"),smm_service_group_id("GRP-SMM-SRV-");
    
    @Getter
    private String groupPrefix;
}

private static HashMap<String,String> getPrefixSequenceNameMap() {

        HashMap<String,String> prefixSequenceNameMap = new HashMap<>();
        prefixSequenceNameMap.put("GRP-MMM-PNL-","mmm_panel_group_id");
        prefixSequenceNameMap.put("GRP-MMM-SRV-","mmm_service_group_id");

        prefixSequenceNameMap.put("GRP-CMS-PNL-","cms_panel_group_id");
        prefixSequenceNameMap.put("GRP-CMS-SRV-","cms_service_group_id");

        prefixSequenceNameMap.put("GRP-SMM-PNL-","smm_panel_group_id");
        prefixSequenceNameMap.put("GRP-SMM-SRV-","smm_service_group_id");

        return prefixSequenceNameMap;
    }

解决方法

没有“应该”。这取决于您想要的。

  • 如果这些值在编译时是已知的,并且不更改,则枚举可能更好。您仍然可以使用地图。
  • 如果仅在运行时知道这些值,或者在程序运行时更改它们,请使用Map。
,

最好只依赖于枚举值,这样您就不必依赖在代码的两个位置维护映射值了-特别重要的是,以后再添加或删除某些值。

此解决方案通过迭代查找组->序列:

public static SequenceName forGroup(String g) {
    for (SequenceName value : values()) {
        if(value.groupPrefix.equals(g)) { // or equalsIgnoreCase
            return value;
        }
    }
    throw new IllegalArgumentException("No sequence with group: "+g);
}
// Call as:
SequenceName.forGroup("GRP-SMM-SRV-").toString()

或者只是根据地图中查找值构建地图:

private static HashMap<String,SequenceName> prefixSequenceNameMap = new HashMap<>();
static {
    for (SequenceName value : values()) {
        prefixSequenceNameMap.put(value.groupPrefix,value);
    }
}
private static HashMap<String,SequenceName> getPrefixSequenceNameMap() {
    return prefixSequenceNameMap;
}
// Call as:
SequenceName.getPrefixSequenceNameMap().get("GRP-SMM-SRV-").toString()