[Java] Map 인터페이스에서 값(value)을 기준으로 정렬하기
Map 인터페이스는 '키(key)' 와 '값(value)' 로 이뤄져있다.
키는 중복이 허용되지 않고, Map 인터페이스의 기준이 된다. 따라서 키가 정렬 기준이다.
만약 TreeMap 을 만들어 다음과 같이 코드를 넣으면 key 기준에 따라 정렬되어 저장된다.
Map<String, Integer> map = new TreeMap<>();
map.put("b", 100);
map.put("a", 90);
map.put("c", 80);
map.put("d", 70);
map.put("e", 60);
Set<Map.Entry<String, Integer>> set = map.entrySet();
System.out.println(set); // [a=90, b=100, c=80, d=70, e=60]
하지만 값(value)을 기준으로 오름차순하고 싶으면 어떻게 해야할까?
바로 EntrySet( ) 과 List, 그리고 Collections.sort( ) 메서드를 이용해서 가능하다.
먼저 EntrySet 객체로 만든 다음, ArrayList 로 변환한다. 그리고 Collections.sort( ) 메서드로 정렬하는데, 이 때 해당 값을 기준으로 비교하도록 정렬 기준을 대입한다.
Map<String, Integer> map = new TreeMap<>();
map.put("b", 100);
map.put("a", 90);
map.put("c", 80);
map.put("d", 70);
map.put("e", 60);
Set<Map.Entry<String, Integer>> set = map.entrySet();
List list = new ArrayList(set);
Collections.sort(list, new Comparator() {
public int compare(Object o1, Object o2) {
if (o1 instanceof Map.Entry && o2 instanceof Map.Entry) {
Map.Entry e1 = (Map.Entry) o1;
Map.Entry e2 = (Map.Entry) o2;
int v1 = ((Integer)e1.getValue()).intValue();
int v2 = (Integer)e2.getValue();
return v1 > v2 ? 1 : (v1 < v2) ? -1 : 0;
}
return 0;
}
});
System.out.println(list); // [e=60, d=70, c=80, a=90, b=100]
위 코드를 보면 다음과 같은 절차로 진행된다.
(1) entrySet( ) 을 통해 Map.Entry 객체를 만들어 Set 에 저장한다.
(2) Collections.sort( ) 메서드를 사용하기 위해 List 로 변환한다.
(3) Collections.sort( ) 메서드에 익명 내부 클래스로 Comparator 인터페이스를 구현해서 값이 정렬의 기준이 되도록 한다.
(4) Comparator 인터페이스의 compare( ) 메서드를 오버라이딩한다. Map.Entry 의 getValue( ) 를 사용해서 값들이 비교 되도록 만든다.
(5) 정렬 끝 !!
정리하면,
- Map.Entry 객체를 Set 에서 List 로 변환.
- Collections.sort( ) 에 Comparator 인터페이스의 compare( ) 메서드를 오버라이딩하여 대입.
이외에 Map.Entry 객체의 comparingByValue( ) 메서드를 사용할 수도 있다.
List 로 바꾼 다음, sort( ) 메서드를 사용할 때, sort( Map.Entry(comparingByValue( ) ) 을 사용하면 값을 기준으로 올림차순이 된다.