将key-> value的hashmap“转置”为value-> key?

时间:2021-04-01 19:16:50

Say I have a map of key -> value pairs, I want to reverse this so that I have a new map which is effectively value -> key (i.e. the old value becomes the new key and the old key becomes the new value).

假设我有一个键 - >值对的映射,我想要反转这个,以便我有一个有效值的新映射 - >键(即旧值变为新键,旧键变为新值)。

Whats the best way to do this? (I am using Java...).

什么是最好的方法呢? (我正在使用Java ......)。

Oh and values are unique.

哦,价值观是独一无二的。

5 个解决方案

#1


12  

Personally I'd use a Guava BiMap to start with (with an implementation such as HashBiMap) and then call inverse() when I wanted to use the values as keys :)

就个人而言,我会使用Guava BiMap(使用HashBiMap等实现),然后在我想将值用作键时调用inverse():)

#2


6  

I think there are enough solutions for your problem here. I just want to point out to be careful, because that may cause data loss if the values are not unique. F.e. if you have the following map:

我认为这里有足够的解决方案来解决你的问题。我只想指出要小心,因为如果值不是唯一的,那么可能会导致数据丢失。 F.E.如果您有以下地图:

A->X
B->Y
C->Y

and inverse it you will have either

反之亦然

X->A
Y->B

or

要么

X->A
Y->C

which depends on the order of the insertions. By inversing it again, you will have one < key , value > pair less.

这取决于插入的顺序。通过再次反转,您将有一个 对更少。 ,value>

#3


5  

Iterate over the entrySet:

迭代entrySet:

for ( Map.Entry<K, V> entry : map.entrySet() ) {
    newMap.put(entry.getValue(), entry.getKey());
}
return newMap;

#4


1  

Map<Type1,Type2> oldmap = getOldMap();
Map<Type2,Type1> newmap = new HashMap<Type2,Type1>();
for(Entry<Type1,Type2> entry : oldmap.entrySet()) {
    newmap.put(entry.getValue(),entry.getKey();
}

#5


0  

You may use any class that implements the "BidiMap" interface in the common collection from Apache (http://commons.apache.org/collections/). This is more efficient because the bidirectional map is constructed when you filled and there is no need to create a new map, which may not be practical when the map is big.

您可以在Apache的公共集合中使用任何实现“BidiMap”接口的类(http://commons.apache.org/collections/)。这样更有效,因为双向地图是在您填充时构建的,并且不需要创建新地图,这在地图很大时可能不实用。

BidiMap aMap = new DualHashBidiMap();
aMap.put("B", "A");
aMap.put("A", "B");
aMap.put("C", "D");
aMap.put("X", "D");
MapIterator it = aMap.mapIterator();
System.out.println("Before Inverse");
while (it.hasNext()) {
    key = it.next();
    value = it.getValue();
    out.println(key + " -> " + value);
}
aMap = aMap.inverseBidiMap();
System.out.println("After Inverse");
it = aMap.mapIterator();
while (it.hasNext()) {
    key = it.next();
    value = it.getValue();
    out.println(key + " -> " + value);
}

Before Inverse
A -> B
B -> A
X -> D
After Inverse
D -> X
A -> B
B -> A

#1


12  

Personally I'd use a Guava BiMap to start with (with an implementation such as HashBiMap) and then call inverse() when I wanted to use the values as keys :)

就个人而言,我会使用Guava BiMap(使用HashBiMap等实现),然后在我想将值用作键时调用inverse():)

#2


6  

I think there are enough solutions for your problem here. I just want to point out to be careful, because that may cause data loss if the values are not unique. F.e. if you have the following map:

我认为这里有足够的解决方案来解决你的问题。我只想指出要小心,因为如果值不是唯一的,那么可能会导致数据丢失。 F.E.如果您有以下地图:

A->X
B->Y
C->Y

and inverse it you will have either

反之亦然

X->A
Y->B

or

要么

X->A
Y->C

which depends on the order of the insertions. By inversing it again, you will have one < key , value > pair less.

这取决于插入的顺序。通过再次反转,您将有一个 对更少。 ,value>

#3


5  

Iterate over the entrySet:

迭代entrySet:

for ( Map.Entry<K, V> entry : map.entrySet() ) {
    newMap.put(entry.getValue(), entry.getKey());
}
return newMap;

#4


1  

Map<Type1,Type2> oldmap = getOldMap();
Map<Type2,Type1> newmap = new HashMap<Type2,Type1>();
for(Entry<Type1,Type2> entry : oldmap.entrySet()) {
    newmap.put(entry.getValue(),entry.getKey();
}

#5


0  

You may use any class that implements the "BidiMap" interface in the common collection from Apache (http://commons.apache.org/collections/). This is more efficient because the bidirectional map is constructed when you filled and there is no need to create a new map, which may not be practical when the map is big.

您可以在Apache的公共集合中使用任何实现“BidiMap”接口的类(http://commons.apache.org/collections/)。这样更有效,因为双向地图是在您填充时构建的,并且不需要创建新地图,这在地图很大时可能不实用。

BidiMap aMap = new DualHashBidiMap();
aMap.put("B", "A");
aMap.put("A", "B");
aMap.put("C", "D");
aMap.put("X", "D");
MapIterator it = aMap.mapIterator();
System.out.println("Before Inverse");
while (it.hasNext()) {
    key = it.next();
    value = it.getValue();
    out.println(key + " -> " + value);
}
aMap = aMap.inverseBidiMap();
System.out.println("After Inverse");
it = aMap.mapIterator();
while (it.hasNext()) {
    key = it.next();
    value = it.getValue();
    out.println(key + " -> " + value);
}

Before Inverse
A -> B
B -> A
X -> D
After Inverse
D -> X
A -> B
B -> A