2016-06-02 1 views
1

this 질문의 해결책을 사용하여 LinkedHashMap에 문자열 값을 정렬하고 있습니다. 그러나 정렬은 단순히 작동하지 않습니다. 여기에 내가 작성한 코드가있다. 자바 8 스트림을 사용하여 HashMap 문자열 값을 정렬하지 않습니다.

Map<Integer, String> sortedMap = myMap.entrySet().stream() 
       .sorted(Map.Entry.comparingByValue()) 
       .collect(Collectors.toMap(Map.Entry<Integer, String>::getKey, 
        Map.Entry<Integer, String>::getValue)); 

myMap = new LinkedHashMap<Integer, String>(sortedMap); 

이상한 것은

모두 comparingByValuecomparingByKey 방법을 사용하는 경우는 Integer 키를 정렬된다는 것이다. 따라서 정확하게 정렬하고 있습니다. String 값은 아니지만 두 경우 모두 Integer 키입니다. 나는 내가 여기서 잘못하고있는 것을 이해하지 못한다.

+3

내 생각 엔'Collectors.toMap'는, 해시 맵에서 그들을 수집하는 순서를 파괴하고 있다는 것이다. –

+0

그건 의미가 있습니다. 그러나, 그것은 여전히 ​​정수 키의 정렬을 설명하지 않습니다. –

+1

정수는 정수 값 자체가 해시로 사용됨에 따라 정렬 된 것처럼 보이지만 더 많은 정수를 추가하자마자 동일한 물통으로 끝나는 여러 항목을 다시 칠하기 때문에 다른 순서를 얻을 수 있습니다. –

답변

6

수집기 toMap 수집기는 HashMap에 요소를 넣으므로 정렬되지 않은 컬렉션에 넣기 때문에 정렬이 도움이되지 않습니다.

은 즉, 오버로드 toMap 방법을 사용하고, 구체적인 예로서 LinkedHashMap을 제공 :

Map<Integer, String> sortedMap = 
    myMap.entrySet() 
      .stream() 
      .sorted(Map.Entry.comparingByValue()) 
      .collect(Collectors.toMap(Map.Entry::getKey, 
            Map.Entry::getValue, 
            (a, b) -> a, //or throw an exception 
            LinkedHashMap::new)); 
+1

기술적으로'toMap'이 반환하는 맵의 종류는 지정되어 있지 않습니다. 현재 Oracle 구현은 실제로'HashMap'을 사용합니다. – Tunaki

+0

예, 죄송합니다. "구현시 맵의 속성에 대한 보증이 없으며 현재 백그라운드에서 HashMap을 사용하고 있습니다. 특정 구현이 필요한 경우 오버로드 된 toMap 메서드를 사용해야합니다." –

2

내 생각 엔 Collectors.toMap이 정렬되지 않은 맵에서 이들을 수집하여 즉시 순서를 파괴한다는 것입니다.

LinkedHashMap에서 직접 수집 해보십시오 :

LinkedHashMap<Integer, String> newMap = new LinkedHashMap<>(); 
Map<Integer, String> sortedMap = myMap.entrySet().stream() 
       .sorted(Map.Entry.comparingByValue()) 
       .collect((k, v) -> newMap.put(k, v)); 
myMap = newMap; 

을 정수 키를 정렬하는 이유에 관해서는 : 이것은 HashMap이 키를 버킷 방법에 따라, 아마도 단순한 우연의 일치입니다.

관련 문제