0

我从我的静态配置中读取了以下格式的地图: Map<String, Map<String, List<String>>> dependentPluginEntityMapString. 此映射中的字符串值实际上来自 ENUM,映射的正确且必需的表示形式是Map<ENUM_A, Map<ENUM_A, List<ENUM_B>>>.

ENUM_A {
 APPLE, BANANA
}

ENUM_B {
ONION, RADDISH
}
  1. 如何将字符串映射转换为带有枚举的映射以Map<ENUM_A, Map<ENUM_A, List<ENUM_B>>>提高类型安全性?

我知道,我可以迭代字符串映射(使用 for 或流)并根据需要创建一个带有枚举的新映射,但寻找更好/更高效和优雅的方式来做到这一点?

这是我的蛮力解决方案。我能做得更好吗?

final Map<ENUM_A, Map<ENUM_A, List<ENUM_B>>> dependentPluginEntityMap = new HashMap<>();

        for (Map.Entry<String, Map<String, List<String>>> dependentPluginEntry:
                dependentPluginEntityMapFromAppConfig.entrySet()) {
            final Map<ENUM_A, List<ENUM_B>> independentPluginMapForEntry = new HashMap<>();

            if (MapUtils.isNotEmpty(dependentPluginEntry.getValue())) {
                for (Map.Entry<String, List<String>> independentPluginEntry:
                        dependentPluginEntry.getValue().entrySet()) {
                    if (CollectionUtils.isNotEmpty(independentPluginEntry.getValue())) {
                        independentPluginMapForEntry.put(ENUM_A.valueOf(independentPluginEntry.getKey()),
                                independentPluginEntry.getValue().stream().map(value -> ENUM_B.valueOf(value))
                                        .collect(Collectors.toList()));
                    }
                }
            }
            dependentPluginEntityMap.put(ENUM_A.valueOf(dependentPluginEntry.getKey()),
                    independentPluginMapForEntry);
        }

  1. 我应该将字符串映射转换为 ENUMMAP ,而不是使用枚举键映射吗?它适用于我的嵌套地图结构吗?

任何线索表示赞赏。

4

1 回答 1

1

如果您定义简单的实用方法来管理从和的转换,多级Map转换会更容易:Map<K,V> to Map<X,Y>List<X> to List<Y>

static <X,Y> List<Y> toList(List<X> list, Function<X,Y> valueMapper) {
    return list.stream().map(valueMapper).toList();
}

static <K,V,X,Y> Map<X, Y> toMap(Map<K, V> map, Function<K,X> keyMapper, Function<V,Y> valueMapper) {
    return map.entrySet().stream()
              .collect(Collectors.toMap(entry -> keyMapper.apply(entry.getKey()),
                                        entry -> valueMapper.apply(entry.getValue())));
}

有了这些定义,您的转换就可以简化为上述应用:

Map<String, Map<String, List<String>>> in = Map.of(
        "APPLE",   Map.of("APPLE", List.of("RADDISH")
                         ,"BANANA", List.of("ONION", "RADDISH"))
        ,"BANANA", Map.of("APPLE", List.of("ONION", "RADDISH")
                         , "BANANA", List.of("ONION"))
        );

Map<ENUM_A, Map<ENUM_A, List<ENUM_B>>> map  
    = toMap(in, ENUM_A::valueOf,
                m -> toMap(m, ENUM_A::valueOf, 
                              list -> toList(list, ENUM_B::valueOf)));

=>
map ={BANANA={BANANA=[ONION]
             , APPLE=[ONION, RADDISH]}
    , APPLE={BANANA=[ONION, RADDISH]
             , APPLE=[RADDISH]}}
于 2021-05-17T18:00:41.423 回答