2010-07-27 1 views
4

키 -> 값 쌍의 맵을 가지고 있다고 가정 해 봅시다.이 맵을 반대로하여 사실상 값 -> 키인 새로운 맵을 갖도록하고 싶습니다 (예 : 이전 값이 새 키가되고 이전 키가 새 값이됩니다.).키 -> 값에 대한 해시 맵을 값 -> 키로 "조 변경"하시겠습니까?

가장 좋은 방법은 무엇입니까? (Java를 사용하고 있습니다 ...).

오 값은 고유합니다.

답변

12

가 개인적으로 (예 HashBiMap로 구현)로 시작하고 inverse()를 호출 할 구아바 BiMap을 사용하십시오 :

+0

나도 +1. ... –

+0

정말 멋집니다. – aeq

+0

값이 고유하지 않은 경우 Guava를 사용하여 Map >을 간단하게 만들 수도 있습니다. ImmutableMultimap.copyOf (Multimaps.forMap (map)). inverse(). asMap); –

5

으로 반복 entrySet 오버 : 나는 키와 값을 사용하고자 할 때

for (Map.Entry<K, V> entry : map.entrySet()) { 
    newMap.put(entry.getValue(), entry.getKey()); 
} 
return newMap; 
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(); 
} 
0

당신은 아파치의 일반적인 컬렉션의 "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 
6

여기에는 문제에 대한 충분한 해결책이 있다고 생각합니다. 값이 고유하지 않으면 데이터 손실이 발생할 수 있으므로주의해야합니다. F.e. 다음지도가있는 경우 :

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

을하고 반전, 당신은 것 중 하나

X->A 
Y->B 

또는 삽입의 순서에 따라

X->A 
Y->C 

. 다시 반대로하면 < 키, 값> 쌍이 작아집니다.

+0

+1은 위험을 지적한 것입니다. – whiskeysierra

+0

Brilliant! 따라서 고유 한 값을 다루지 않으면 Map을 다차원 배열로 덤프하고이를 조 변경해야합니다. 그런 다음 "있는 그대로"사용하십시오. – Bostone

관련 문제