3

キーが文字列で、値がコンマで区切られた値のリストであるマップがあります。

キーと値のペアの順序を逆にして、キーが値になり、値がキーになるように新しいマップに割り当てるにはどうすればよいですか?

それで :

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

になります:

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

考えられる解決策は、各値を反復処理してから、すべてのキーを反復処理して、対応する同じ値を検索することです。見つかった場合は、この新しいキーと値のペアを新しいマップに追加します。これは非効率に思えますか?

解決策(受け入れられた回答を使用して実装):

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);
        }
    }

}
4

5 に答える 5

3

マップをマップするものがたくさんあるようです。

これは、を使用して表すことができます

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());
    }
}
于 2012-09-17T11:07:11.213 に答える
2
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());
    }
}

これは逆マップの文字列をソートしないことに注意してください。これを行うには、文字列を分割して再結合する逆マップを介して2回目の反復を実行します。

より良い解決策は、データを次のようにモデル化することです。SortedMap<String,SortedSet<String>>

于 2012-09-17T11:11:27.920 に答える
2

Google GuavaのBiMapを使用できます:

 BiMap<?, ?> bimap = HashBiMap. create();
 BiMap<?, ?> reverse = bimap.inverse(); // Do this only once after the BiMap has been created.
于 2012-09-17T11:15:57.727 に答える
1

値がリストの場合、これはおそらく役立つでしょう:

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);
        }
    }
}
于 2012-09-17T11:49:49.870 に答える
0
Map<Value, Key> reverseMap = new HashMap<Value, Key>();
for (Map.Entry<Key, Value> entry : map) {
    reverseMap.put(entry.getValue(), entry.getKey());
}

元のマップでは各(キー、値)ペアが異なるため、マップを反転するプロセス中に上書きが発生しないことを前提としています。

于 2012-09-17T11:02:05.650 に答える