【问题标题】:Reduce a Map where the keys are values in some entries减少一个 Map,其中键是某些条目中的值
【发布时间】:2019-01-11 14:26:55
【问题描述】:

我正在尝试从另一个 Map 创建一个新 Map,其中一些值是其他条目中的键。

例子:

HashMap<String,String> testMap = new HashMap<>();
testMap.put("a","b");
testMap.put("b","d");
testMap.put("d","e");
testMap.put("e","f");
testMap.put("k","r");

我需要一个具有这种格式的新地图:

a-&gt;f
b-&gt;f
d-&gt;f
e-&gt;f
k-&gt;r

producedMap.put("a","f");
producedMap.put("b","f");
producedMap.put("d","f");
producedMap.put("e","f");
producedMap.put("k","r");

我的代码是这样的,但似乎没有给出真实的结果。

    public HashMap<String,String> getMatched(HashMap<String,String> correpondanceMap){

    Collection<String> correpondanceKeys = correpondanceMap.keySet();
    HashMap<String,String> newCorrepondanceMap= new HashMap<>();
    correpondanceMap.entrySet().forEach(entry->{
        if (correpondanceKeys.contains(entry.getValue())){
            String newValue = entry.getValue();
            String keyOfnewValue = correpondanceMap
                    .entrySet()
                    .stream()
                    .filter(entriii -> newValue.equals(entry.getValue()))
                    .map(Map.Entry::getKey).limit(1).collect(Collectors.joining());


            newCorrepondanceMap.put(keyOfnewValue,correpondanceMap.get(newValue));
        }
        else
        {
            newCorrepondanceMap.put(entry.getKey(),entry.getValue());
        }
    });

    newCorrepondanceMap.entrySet().forEach(entry-> System.out.println(entry.getKey() +"  -- > " +entry.getValue()));

    return newCorrepondanceMap;
}

【问题讨论】:

  • 能不能把目前制作的地图贴出来,这样更容易发现你的问题
  • @Lino 如果我们有 ("a","b") 和某处 ("b","d"),我们只需将键“a”重定向到值“d”跨度>
  • 您的问题和代码不清楚。除了a-&gt;fb-&gt;f 等之外,重新映射键和值的实际规则是什么?
  • 不,我的意思是您当前代码的输出。例如。运行代码时打印的内容
  • @JustinAlbano 这是一个 HashMap;因此键的顺序是不可预测的。

标签: java dictionary hashmap


【解决方案1】:

您可以通过辅助函数中的一些简单递归逻辑来实现:

public static String findCorrespondingValue(Map<String, String> map, String key){
    if(map.containsKey(key)){
        return findCorrespondingValue(map, map.get(key));
    }
    return key;
}

如上所述,逻辑非常简单,我们只检查给定key 是否存在给定map 中的值

  • 如果是,我们将再次执行该函数,但这次使用value 作为 新的key
  • 如果不存在映射,我们可以肯定地说给定的key 是最后一个 价值链

你可以这样调用方法:

Map<String, String> testMap = ... // setup testMap

Map<String, String> result = new HashMap<>();
for (final Entry<String, String> entry : testMap.entrySet()) {
    result.put(
        entry.getKey(), 
        findCorrespondingValue(testMap, entry.getValue())
    );
}

或者如果你碰巧使用了 java 8:

Map<String, String> result = testMap.entrySet().stream()
    .collect(Collectors.toMap(
        e -> e.getKey(),  // or just Map.Entry::getKey
        e -> findCorrespondingValue(e.getValue())
     ));

您当然必须实现某种逻辑来确定您是否有循环引用。例如:

a -> b
b -> f
f -> a

目前这会失败,StackOverflowError


如果您想支持多种不同的类型,也可以将其设为通用,而不仅仅是String

public static <T> T findCorrespondingValue(Map<? extends T, ? extends T> map, T key){
    if(map.containsKey(key)){
        return findCorrespondingValue(map, map.get(key));
    }
    return key;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-01-31
    • 2021-04-27
    • 1970-01-01
    • 1970-01-01
    • 2017-04-10
    • 2020-09-04
    • 1970-01-01
    • 2021-11-01
    相关资源
    最近更新 更多