Development Tip

Java에서 HashMap 키 및 값 반전

yourdevel 2020. 12. 10. 21:22
반응형

Java에서 HashMap 키 및 값 반전


간단한 질문입니다. 키와 값을 반대로 바꾸고 싶은 간단한 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'.

다 독특 해 yes

값이 고유하다고 확신하는 경우 이전지도의 항목을 반복 할 수 있습니다.

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

마지막으로 Stream API에 대한 유틸리티 메서드가 포함 된 proton pack 라이브러리 에 저의 기여를 추가했습니다 . 이를 통해 다음과 같이 할 수 있습니다.

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

Apache commons collections 라이브러리는 맵 반전을위한 유틸리티 메소드를 제공합니다. myHashMap의 값이 고유 한 경우이를 사용할 수 있습니다.

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

샘플 코드

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

값이 고유하지 않은 경우 맵을 반전하는 안전한 방법은 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())))

나는 또한 작동하는 더 간단한 루프를 작성했습니다 (모든 값이 고유하다는 점에 유의하십시오).

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

어떻게 할 수 있는지에 대한 질문에 답하려면 지도 에서 entrySet을 가져온 다음 getValue as keygetKey as를 사용하여 새지도에 넣을 수 value있습니다.

그러나 맵의는 고유합니다. 즉, 원래 맵에 두 개의 다른 키가있는 하나의 값이있는 경우 두 번째 키 (반복 순서) 만 새 맵의 값으로 유지됩니다.


키 및 값 목록을 반복 한 다음 추가합니다.

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

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동일한 키로 호출 될 때 값 대체 한다는 것을 기억하는 것이 중요합니다 . 따라서 맵에 동일한 값을 가진 두 개의 키가있는 경우 그 중 하나만 반전 된 맵에 존재합니다.


아래 샘플 스 니펫으로 테스트하고 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}

참고 URL : https://stackoverflow.com/questions/20412354/reverse-hashmap-keys-and-values-in-java

반응형