2016-12-06 1 views
2

원본지도를 뒤집을 필요가 있습니다. 어떤 유형이 <Integer, String>입니다 (예 : {1 = A, 2 = A, 3 = B....}). String ~ ArrayList 인 새로운지도를 만들고 싶습니다. 과 같은 것을 가지고 있기 때문에 1 = A2 = A 인 경우보다 유용합니다.자바가지도를 뒤집습니다.

어떻게하면됩니까?

+1

기존지도를 반복합니까? – BevynQ

+0

http://stackoverflow.com/questions/3678601/how-to-do-map-inversion-with-guava-with-non-unique-values ​​ –

+0

그래, 한 번 반복하고 키 또는 값을 가져와야한다고 생각합니다. 가장 작은. – Anderson

답변

3

이 작업을 시도 할 수 있습니다 :

HashMap<Integer, String> original = new HashMap<>(); 
HashMap<String, ArrayList<Integer>> inverted = new HashMap<>(); 

original.put(1, "A"); 
original.put(2, "B"); 
original.put(3, "C"); 
original.put(4, "A"); 

for (Integer key: original.keySet()) { 
    String newKey = original.get(key); 

    inverted.computeIfAbsent(newKey, k -> new ArrayList<>()); 
    inverted.get(newKey).add(key); 

} 
System.out.println(original); 
System.out.println(inverted); 

는 자, HashMap<Integer, String> original을 가정 해 봅시다 {1=A, 2=B, 3=C, 4=A}입니다, 당신은 {A=[1, 4], B=[2], C=[3]}을 얻을 것이다.

편집 : 당신이 제안했다 @ Mr.Polywhirl으로 더 일반적인 버전을 원한다면, 당신은 사용할 수 있습니다

public static final <T, U> Map<U, List<T>> invertMap(Map<T, U> map) { 
    HashMap<U, List<T>> invertedMap = new HashMap<>(); 

    for (T key : map.keySet()) { 
     U newKey = map.get(key); 

     invertedMap.computeIfAbsent(newKey, k -> new ArrayList<>()); 
     invertedMap.get(newKey).add(key); 

    } 

    return invertedMap; 
} 
+0

이 문제는 게시 한 원래 버전과 달리 색인 당 2 개의 해시 조회가 필요하다는 것을 의미합니다. 해시가 예제와 같이 사소한 것이라면 아무 것도 없습니다. 수백 개의 아이템이 있다면, 속도 향상을 위해 다른 방법을 사용해야합니다. 여기에 1을 초과해서는 안됩니다 (computeIfAbsent는 아이템이 있는지 확인해야합니다). –

+0

@GabeSechan, 내 대답을 편집하여이 코드를보다 효율적으로 만들 수 있습니다. 나는 자바를 잘 모른다. – lmiguelvargasf

+0

다음은 위 코드의 일반적인 버전입니다. 자유롭게 응답에 추가하십시오. http://pastebin.com/yTExx5Fi –

4

쉽게 아래 예를 들어, 그것은 자바 (8)의 stream API를 사용하여 수행 할 수 있습니다 :

public static void main(String[] args) throws FileNotFoundException { 

    Map<Integer, String> map = new HashMap<>(); 
    map.put(1, "A"); 
    map.put(2, "A"); 
    map.put(3, "B"); 

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

    System.out.println(invertedMap); 

} 
+1

사람들이 왜 이와 같은 문제에 대해 스트림 접근 방식을 선호하는지 이해가 안됩니다. 그것은 비 직관적 인 비 자체 문서화 코드 인 것 같습니다. 이것이 전통적인 루핑 예제보다 어떻게 더 좋은가? – bhspencer

+1

나는 잘못하지 않았기 때문에 downvote하지 않을 것이지만, 나는 이것을 codereview에서 반송 할 것이다. 코드가하는 일을 파악하기가 너무 어려우며, 요구 사항을 변경해도 제자리에서 변경할 방법이 없다면 완전히 다시 작성해야합니다. –

+2

일반적인 논의는 Java가 이미 라이브러리/API를 제공하는 경우 자체 원형 코드 (Java의 네이티브 API만큼 효율적이지는 않음)를 작성하는 것보다 사용하는 것이 좋습니다. –

관련 문제