Java 中的反向 HashMap 键和值

问题描述 投票:0回答:13

这是一个简单的问题, 我有一个简单的 HashMap,我想反转其中的键和值。

HashMap<Character, String> myHashMap = new HashMap<Character, String>();
myHashMap.put('a', "test one");
myHashMap.put('b', "test two");

我想创建一个新的 HashMap,在其中放入相反的内容。

HashMap<String, Character> reversedHashMap = new HashMap<String, Character>();
e.g. Keys "test one" & "test two" and values 'a' & 'b'.
java hashmap
13个回答
156
投票

它们都是独一无二的,是的

如果您确定您的值是唯一的,您可以迭代旧地图的条目。

Map<String, Character> myNewHashMap = new HashMap<>();
for(Map.Entry<Character, String> entry : myHashMap.entrySet()){
    myNewHashMap.put(entry.getValue(), entry.getKey());
}

或者,您可以使用像Guava提供的双向地图并使用

inverse()
方法:

BiMap<Character, String> myBiMap = HashBiMap.create();
myBiMap.put('a', "test one");
myBiMap.put('b', "test two");

BiMap<String, Character> myBiMapInversed = myBiMap.inverse();

由于 已经出来了,你也可以这样做:

Map<String, Integer> map = new HashMap<>();
map.put("a",1);
map.put("b",2);

Map<Integer, String> mapInversed = 
    map.entrySet()
       .stream()
       .collect(Collectors.toMap(Map.Entry::getValue, Map.Entry::getKey))

最后,我添加了对 proton pack 库 的贡献,其中包含 Stream API 的实用方法。这样你就可以这样做:

Map<Character, String> mapInversed = MapStream.of(map).inverseMapping().collect();

31
投票

Apache commons 集合库提供了一种用于反转映射的实用方法。如果您确定 myHashMap 的值是唯一的,则可以使用它

org.apache.commons.collections.MapUtils.invertMap(java.util.Map map)

示例代码

HashMap<String, Character> reversedHashMap = MapUtils.invertMap(myHashMap) 

29
投票

如果值不唯一,反转映射的安全方法是使用 java 8 的 groupingBy 函数

Map<String, Integer> map = new HashMap<>();
map.put("a",1);
map.put("b",2);

Map<Integer, List<String>> mapInversed = 
map.entrySet()
   .stream()
   .collect(Collectors.groupingBy(Map.Entry::getValue, Collectors.mapping(Map.Entry::getKey, Collectors.toList())))

3
投票

我编写了一个更简单的循环,也可以工作(请注意,我的所有值都是唯一的):

HashMap<Character, String> myHashMap = new HashMap<Character, String>();
HashMap<String, Character> reversedHashMap = new HashMap<String, Character>();

for (char i : myHashMap.keySet()) {
    reversedHashMap.put(myHashMap.get(i), i);
}

2
投票

要回答有关如何做到这一点的问题,您可以从地图中获取 entrySet,然后使用 getValue 作为

key
getKey 作为
value
放入新地图中。

但请记住,Map中的键是唯一的,这意味着如果原始映射中的一个值具有两个不同的键,则只有第二个键(按迭代顺序)将保留为新映射中的值。


2
投票

遍历键和值列表,然后添加它们。

HashMap<String, Character> reversedHashMap = new HashMap<String, Character>();
for (String key : myHashMap.keySet()){
    reversedHashMap.put(myHashMap.get(key), key);
}

2
投票
private <A, B> Map<B, A> invertMap(Map<A, B> map) {
    Map<B, A> reverseMap = new HashMap<>();
    for (Map.Entry<A, B> entry : map.entrySet()) {
        reverseMap.put(entry.getValue(), entry.getKey());
    }
    return reverseMap;
}

重要的是要记住,当使用相同的键调用时,

put
会替换该值。因此,如果您的地图有两个具有相同值的键,则只有其中一个会存在于倒置地图中。


2
投票

使用下面的示例片段进行测试,尝试使用 MapUtils 和 Java8 Stream 功能。它适用于两种情况。

public static void main(String[] args) {
    Map<String, String> test = new HashMap<String, String>();
    test.put("a", "1");
    test.put("d", "1");
    test.put("b", "2");
    test.put("c", "3");
    test.put("d", "4");
    test.put("d", "41");

    System.out.println(test);

    Map<String, String> test1 = MapUtils.invertMap(test);

    System.out.println(test1);

    Map<String, String> mapInversed = 
            test.entrySet()
               .stream()
               .collect(Collectors.toMap(Map.Entry::getValue, Map.Entry::getKey));

    System.out.println(mapInversed);
}

Output:
{a=1, b=2, c=3, d=41}
{1=a, 2=b, 3=c, 41=d}
{1=a, 2=b, 3=c, 41=d}

1
投票

使用Java 8中引入的forEach

Map<Short, String> regularMap = new HashMap<>();
Map<String, Short> inversedMap = new HashMap<>();

regularMap.forEach((key, value) -> inversedMap.put(value, key));

0
投票

要恢复地图,在您的情况下:

private void reverseMap(Map<Character, String> map) {
    Map<String, Character> newList = new HashMap<>();
    map.forEach((key, value) -> newList.put(value, key));
    System.out.println(newList);
}

或者你可以遍历旧的哈希图

HashMap<String, Character> newList = new HashMap<String, Character>();
for (String key : list.keySet()){
   newList.put(list.get(key), key);
}

0
投票

用于反转字典数组。 (如果值是唯一的)

private void reverseArrayMap(List<Map<String, String>> list) {
    // reversing the array of dictionary
    List<Map<String, String>> newList = new ArrayList<>();
    Map<String, String> resDic = new HashMap<>();

    for (Map<String, String> map : list) {
        map.forEach((key, value) -> resDic.put(value, key));
        newList.add(resDic);
    }

    System.out.println("Original Array of Dictionary" + list);
    System.out.println("Reversed Array of Dictionary" + newList);
}      

0
投票

Java:
简单的方法,不需要 java 8

Map<String,String> map=new HashMap<>();
Map<String,String> mapInv=new HashMap<>();

for (String key : map.keySet()) 
        mapInv.put(map.get(key), key);

Java 8:

forEach()
是一种迭代元素的新方法。它在 Iterable 和 Stream 接口中定义。

Map<String,String> map=new HashMap<>();
Map<String,String> mapInv=new HashMap<>();

map.forEach((key, value) -> mapInv.put(value, key));

科特林:

    val map: Map<String, String> = HashMap()
    val mapInv: MutableMap<String?, String> = HashMap()

    for (key in map.keys) mapInv[map[key]] = key

0
投票
Map<String, Character> inverted = myHashMap.entrySet().stream()
        .collect(Collectors.toMap(Map.Entry::getValue, Map.Entry::getKey));

这会流过映射的条目集,并将其收集回映射中,并交换键和值。

这确实假设地图中没有任何重复值。如果存在重复值,则按照另一个答案中的建议使用

groupingBy
是一个很好的建议,因为倒排映射的每个值都将是一个或多个元素的列表。

© www.soinside.com 2019 - 2024. All rights reserved.