简体   繁体   English

如何在Map中转换键/值

[英]How to transform key/value in Map

I have a Map where key is a String and value is comma seperated list of values. 我有一个Map,其中key是一个String,值是逗号分隔的值列表。

How can I reverse the ordering of the key/value pairs and assign to new Map so that keys become values and the values become keys 如何反转键/值对的顺序并分配给新的Map,以便键成为值,值成为键

So : 所以:

 key value key1 value1,value2,value3 key2 value1,value4,value5 key3 value4,value2,value1 

becomes : 成为:

 key value value1 key1,key2,key3 value2 key1,key3 value3 key1 value4 key2,key3 value5 key2 

A possible solution is to iterate over each value and then iterate of every key searching for same corresponding value. 一种可能的解决方案是迭代每个值,然后迭代搜索相同对应值的每个键。 If found add this new key/value pair to a new Map. 如果找到,则将此新键/值对添加到新Map。 This seems inefficient ? 这似乎效率低下?

Solution (implemented using accepted answer) : 解决方案(使用接受的答案实施):

import java.util.HashMap;
import java.util.Map;

public class MapTransformer {

    public static void main(String args[]) {

        Map<String, String> m1 = new HashMap<String, String>();

        m1.put("key1", "value1,value2");
        m1.put("key2", "value5");
        m1.put("key3", "value4,value2,value1");

        Map<String, String> inverseMap = new HashMap<String, String>();
        for (Map.Entry<String, String> entry : m1.entrySet()) {
            for (String value : entry.getValue().split(",")) {
                if (inverseMap.containsKey(value))
                    inverseMap.put(value, inverseMap.get(value) + "," + entry.getKey());
                else
                    inverseMap.put(value, entry.getKey());
            }
        }

        for (Map.Entry<String, String> entry : inverseMap.entrySet()) {
            String key = entry.getKey();
            String value = entry.getValue();
            System.out.println(key+" "+value);
        }
    }

}

It appears you have a many to map Map. 看来你有很多地图来映射。

This can be represented using 这可以使用表示

Map<K, List<V>> map1 = new LinkedHashMap<K, List<V>>();
Map<V, List<K>> map2 = new LinkedHashMap<V, List<K>>();
for (Map.Entry<K, List<V>> entry : map1.entrySet()) {
    for (V v : entry.getValue()) {
        List<K> list2 = map2.get(v);
        if (list2 == null)
            map2.put(v, list2 = new ArrayList<K>());
        list2.add(entry.getKey());
    }
}
Map<String,String> initialMap = ...
Map<String,String> inverseMap = new HashMap<String,String>();
for (Map.Entry<String,String> entry: initialMap.entrySet()) {
    for (String v : entry.getValue().split(",")) {
        if (inverseMap.containsKey(v)) 
          inverseMap.put(v,inverseMap.get(v)+","+entry.getKey());
        else
          inverseMap.put(v, entry.getKey());
    }
}

Note that this does not sort the strings in the inverse map. 请注意,这不会对逆映射中的字符串进行排序。 To do that you then do a second iteration through the inverse map splitting and rejoining the strings. 为此,您可以通过逆映射拆分和重新连接字符串进行第二次迭代。

A better solution is to model the data as a SortedMap<String,SortedSet<String>> 更好的解决方案是将数据建模为SortedMap<String,SortedSet<String>>

You can use Google Guava's BiMap : 您可以使用Google Guava的BiMap

 BiMap<?, ?> bimap = HashBiMap. create();
 BiMap<?, ?> reverse = bimap.inverse(); // Do this only once after the BiMap has been created.

If value is list this maybe help: 如果值是列表,这可能有帮助:

Map<String, List<String>> reverseMap = new HashMap<String, List<String>>();

for(Entry`<String, List<String>>` entry : map.entrySet())
{
    for(String str : entry.getValue())
    {
        if(reverseMap.get(str) != null){
            reverseMap.get(str).add(entry.getKey());            
        } else {
            List<String> list = new ArrayList<String>();
            list.add(entry.getKey());
            reverseMap.put(str, list);
        }
    }
}
Map<Value, Key> reverseMap = new HashMap<Value, Key>();
for (Map.Entry<Key, Value> entry : map) {
    reverseMap.put(entry.getValue(), entry.getKey());
}

The assumption is that each (key, value) pair is distinct in the original map, so there are no overwrites during the process of reversing the map. 假设每个(键,值)对在原始地图中是不同的,因此在反转地图的过程中不会有覆盖。

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

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