繁体   English   中英

反转地图 | 值 ---> 键

[英]Invert Map | Values ---> Keys

我希望能够反转具有多个键可以指向相同值的给定 HashMap。

HashMap<String, String> cities = new HashMap<String, String>();

        cities.put("Manchester", "UK");
        cities.put("London", "UK");
static HashMap<String, String> inverseMap(HashMap map) {
       // something that has "UK" point to both "Manchester" and "London"

      // if it can be done without using any special Java 8 feature, that would be great
}

我不确定从哪里开始。

像这样做。 基本上,它使用合并函数来连接重复键的值。

  • 创建新地图
  • 使用旧地图的值作为新地图的键
  • 如果新映射没有键的值,则将值放入新映射中
  • 否则,将该值连接到该键的旧值
        HashMap<String, String> cities = new HashMap<String, String>();

        cities.put("Manchester", "UK");
        cities.put("London", "UK");
        cities.put("New York", "US");
        cities.put("Chicago", "US");

        Map<String,String> inverted = new HashMap<>();
        for (String key : cities.keySet()) {
            String newKey = cities.get(key);
            String value = inverted.get(newKey);
            if (value == null) {
                inverted.put(newKey, key);
            } else {
                value = value + ", " + key;
                inverted.put(newKey, value);
            }

        }
        for (Entry<String,String> e : inverted.entrySet()) {
            System.out.println(e.getKey() + " -> " + e.getValue());
        }

它打印

UK -> Manchester, London
US -> New York, Chicago

由于您没有指定如何处理重复键。 我也可以将它存储在Map<String,List<String>>

由于多个键可以包含相同的值,因此您必须能够在逆映射中为每个键存储多个值。 我建议使用 Set 作为这个值。

  • 创建一个可以将一组字符串保存为值的地图
  • 遍历原始地图
  • 如果在新地图中找不到该国家/地区,请在那里创建一个条目
  • 将城市添加到地图

这也应该适用于没有依赖关系的 Java 7。

static HashMap<String, Set<String>> inverseMap(HashMap<String,String> map) {
    HashMap<String,Set<String>> inversed=new HashMap<>();
    for(Map.Entry<String,String> entry:map.entrySet()){
        if(!inversed.containsKey(entry.getValue())){
            inversed.put(entry.getValue(),new HashSet<>());
        }
        inversed.get(entry.getValue()).add(entry.getKey());
    }
    return inversed;
}

{Manchester=UK,London=UK}将变成{UK={Manchester,London}} (顺序可能不同)。

这是你要找的吗?

Map<String, String> cities = new HashMap<>();
cities.put("Manchester", "UK");
cities.put("London", "UK");
Map<String, List<String>> reverseMap = new HashMap<>();
for (Entry<String, String> entry : cities.entrySet()) {
     List<String> list = reverseMap.get(entry.getValue());
     if (list == null) {
         list = new ArrayList<>();
         reverseMap.put(entry.getValue(), list);
     }
     list.add(entry.getKey());
}

System.out.println(reverseMap);

你可以看看MultiMap。 它允许将单个键映射到多个值。

这是谷歌番石榴https://guava.dev/releases/19.0/api/docs/com/google/common/collect/Multimap.html

ListMultimap<String, String> multimap = ArrayListMultimap.create();
   for (President pres : US_PRESIDENTS_IN_ORDER) {
     multimap.put(pres.firstName(), pres.lastName());
   }
   for (String firstName : multimap.keySet()) {
     List<String> lastNames = multimap.get(firstName);
     out.println(firstName + ": " + lastNames);
   }
... produces output such as:
   Zachary: [Taylor]
   John: [Adams, Adams, Tyler, Kennedy]  // Remember, Quincy!
   George: [Washington, Bush, Bush]
   Grover: [Cleveland, Cleveland]        // Two, non-consecutive terms, rep'ing NJ!

在 Apache Commons Collections https://commons.apache.org/proper/commons-collections/apidocs/org/apache/commons/collections4/MultiValuedMap.html

     MultiValuedMap<K, String> map = new MultiValuedHashMap<K, String>();
     map.put(key, "A");
     map.put(key, "B");
     map.put(key, "C");
    Collection<String> coll = map.get(key);
coll will be a collection containing "A", "B", "C".

您可以遍历原始地图的条目集并使用值(国家/地区代码)作为键并将每个键(城市)添加到列表中:

static HashMap<String, List<String>> inverseMap(HashMap<String, String> map) {
   HashMap<String, List<String>> countryToCity = new HashMap<>();
   for(Map.Entry<String,String> entry: map.entrySet()){
       countryToCity.computeIfAbsent(entry.getValue(), k -> new ArrayList<>()).add(entry.getKey());
   }
   return countryToCity;
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM