2023. 1. 6. 01:03ㆍJava
백준 1339 단어 수학 문제를 풀다가 HashMap을 Value 기준으로 정렬하고자 HashMap 정렬에 대해 찾아보게 되었다.
HashMap은 키와 값 기준으로 정렬이 가능한데, 그 방법에 대해 알아보자.
HashMap이란

HashMap은 입력하는 데이터의 순서를 보장하지 않는다.
또한, HashMap은 키의 해시 값을 기준으로 각 entry를 정렬할 뿐, 키와 값 기준으로 정렬되지는 않는다.
따라서 HashMap을 키와 값을 기준으로 정렬하기 위해서는 다른 자료구조를 이용해야만 한다.
1. Comparator 사용
comparator를 람다로 구현하여 오름차순, 내림차순 정렬할 수 있다.
내림차순의 경우 순서만 바꿔주면 된다.
1-1. key 값 정렬
이 경우, map의 keySet을 이용하여 정렬한다.
keySet()은 map에 저장된 모든 key를 List로 리턴한다.
map과 달리 List는 순서가 있는 자료구조이므로 정렬이 가능하게 된다.
- 오름차순 정렬
import java.util.*;
public class Example {
public static void main(String[] args){
Map<String, Integer> map = new HashMap<>();
map.put("A", 12);
map.put("B", 2);
map.put("C", 5);
map.put("D", 1);
map.put("E", 17);
//keySet을 이용하여 list로 저장한다
List<String> keyList = new ArrayList<>(map.keySet());
//오름차순 정렬한다
keyList.sort((o1, o2) -> o1.compareTo(o2));
//결과 출력
for(String key : keyList){
System.out.println("key: " + key + ", value: " + map.get(key));
}
}
}
결과
key: A, value: 12
key: B, value: 2
key: C, value: 5
key: D, value: 1
key: E, value: 17
- 내림차순 정렬
keyList.sort((o1, o2) -> o2.compareTo(o1));
- 메소드 레퍼런스 사용
메소드 레퍼런스는 메소드를 className::methodName 형식으로 호출한다.
위의 람다식을 메소드 레퍼런스로 변경하면 밑의 예제와 같다.
import java.util.*;
public class Example {
public static void main(String[] args){
Map<String, Integer> map = new HashMap<>();
map.put("A", 12);
map.put("B", 2);
map.put("C", 5);
map.put("D", 1);
map.put("E", 17);
//keySet을 이용하여 list로 저장한다
List<String> keyList = new ArrayList<>(map.keySet());
//오름차순 정렬한다
keyList.sort(String::compareTo);
//결과 출력
for(String key : keyList){
System.out.println("key: " + key + ", value: " + map.get(key));
}
}
}
1-2. value 값 정렬
이 경우, map의 values()를 이용하여 정렬한다.
values()는 모든 value들을 List로 리턴한다.
2. Comparable<T> 인터페이스 사용
java.util.Collections 클래스의 sort() 메소드를 사용한다.
2-1. key 값 정렬
- 오름차순 정렬
import java.util.*;
public class Example {
public static void main(String[] args){
Map<String, Integer> map = new HashMap<>();
map.put("A", 12);
map.put("B", 2);
map.put("C", 5);
map.put("D", 1);
map.put("E", 17);
//keySet을 이용하여 list로 저장한다
List<String> keyList = new ArrayList<>(map.keySet());
//오름차순 정렬한다
Collections.sort(keyList);
//결과 출력
for(String key : keyList){
System.out.println("key: " + key + ", value: " + map.get(key));
}
}
}
- 내림차순 정렬
Collections.reverse(keyList);
2-2. value 값 정렬
key 값 정렬과 동일하다. keySet대신 values를 이용한다.
3. Entry 내장 함수 사용
Map.Entry의 comparingByKey, comparingByValue함수를 사용한다.
3-1. key 값 정렬
import java.util.*;
public class Example {
public static void main(String[] args){
Map<String, Integer> map = new HashMap<>();
map.put("A", 12);
map.put("B", 2);
map.put("C", 5);
map.put("D", 1);
map.put("E", 17);
//entrySet을 이용하여 list로 저장한다
List<Map.Entry<String, Integer>> entryList = new LinkedList<>(map.entrySet());
//오름차순 정렬한다
entryList.sort(Map.Entry.comparingByKey());
//결과 출력
for(Map.Entry<String, Integer> entry : entryList){
System.out.println("key: " + entry.getKey() + ", value: " + entry.getValue());
}
}
}
3-2. value 값 정렬
comparingByKey 함수 대신 comparingByValue 함수를 사용한다.
entryList.sort(Map.Entry.comparingByValue());
4. TreeMap 사용(Key 정렬 시에만)
TreeMap은 SortedMap 인터페이스를 상속받아 구현한다.
TreeMap에는 Comparator를 인자로 전달할 수 있어, Comparator를 정의함으로써 정렬 기준을 정할 수 있다.
생략시에는 기본 Comparator가 사용되며, 이 경우 TreeMap에 객체를 저장하면, key가 오름차순 정렬되어 저장된다.
이 TreeMap을 사용하여 key값을 기준으로 HashMap을 정렬시킬 수 있다.
- 기본 Comparator 사용 - 오름차순 정렬
import java.util.*;
public class Example {
public static void main(String[] args){
Map<String, Integer> map = new HashMap<>();
map.put("A", 12);
map.put("B", 2);
map.put("C", 5);
map.put("D", 1);
map.put("E", 17);
TreeMap<String, Integer> treeMap = new TreeMap<String, Integer>(map);
//결과 출력
for(Map.Entry<String, Integer> entry : treeMap.entrySet()){
System.out.println("key: " + entry.getKey() + ", value: " + entry.getValue());
}
}
}
- 역순 정렬
import java.util.*;
public class Example {
public static void main(String[] args){
Map<String, Integer> map = new HashMap<>();
map.put("A", 12);
map.put("B", 2);
map.put("C", 5);
map.put("D", 1);
map.put("E", 17);
TreeMap<String, Integer> treeMap = new TreeMap<String, Integer>(Collections.reverseOrder());
treeMap.putAll(map);
//결과 출력
for(Map.Entry<String, Integer> entry : treeMap.entrySet()){
System.out.println("key: " + entry.getKey() + ", value: " + entry.getValue());
}
}
}
- 사용자 정의 Comparator 사용
import java.util.*;
public class Example {
public static void main(String[] args){
Map<String, Integer> map = new HashMap<>();
map.put("ABC", 12);
map.put("B", 2);
map.put("C", 5);
map.put("DE", 1);
map.put("E", 17);
Comparator<String> comparator = Comparator.comparingInt(String::length).thenComparing(o -> o);
TreeMap<String, Integer> treeMap = new TreeMap<>(comparator);
treeMap.putAll(map);
//결과 출력
for(Map.Entry<String, Integer> entry : treeMap.entrySet()){
System.out.println("key: " + entry.getKey() + ", value: " + entry.getValue());
}
}
}
5. LinkedHashMap 사용
LinkedHashMap은 HashMap과 달리 입력된 순서가 보장되는 클래스이다.
즉, 입력하는 순서대로 정렬되고 꺼낼 수 있다.
HashMap의 entry를 원하는 기준으로 정렬하고, 이를 LinkedHashMap에 차례로 저장하면 HashMap 정렬 결과를 얻을 수 있다.
5-1. key 값 정렬
import java.util.*;
public class Example {
public static LinkedHashMap<String, Integer> sortMap(Map<String, Integer> map){
//entry 리스트 생성
List<Map.Entry<String, Integer>> entries = new LinkedList<>(map.entrySet());
//정렬
Comparator<Map.Entry<String, Integer>> comparator = Map.Entry.comparingByKey();
entries.sort(comparator);
LinkedHashMap<String, Integer> result = new LinkedHashMap<>();
for(Map.Entry<String, Integer> entry:entries){
result.put(entry.getKey(), entry.getValue());
}
return result;
}
public static void main(String[] args){
Map<String, Integer> map = new HashMap<>();
map.put("A", 12);
map.put("B", 2);
map.put("C", 5);
map.put("F", 1);
map.put("E", 17);
Map<String, Integer> result = sortMap(map);
//결과 출력
for(Map.Entry<String, Integer> entry : result.entrySet()){
System.out.println("key: " + entry.getKey() + ", value: " + entry.getValue());
}
}
}
5-2. value 값 정렬
Comparator를 다음과 같이 바꿔주면 된다.
Comparator<Map.Entry<String, Integer>> comparator = Map.Entry.comparingByValue();
참고자료
https://heestory217.tistory.com/entry/Sort-a-HashMap-in-Java-1-TreeMap
https://developer-talk.tistory.com/395
https://codechacha.com/ko/java-sort-map/
'Java' 카테고리의 다른 글
[JAVA]컬렉션 프레임워크(Collections Framework) (0) | 2023.01.15 |
---|---|
[JAVA] 객체지향 프로그래밍2 (0) | 2023.01.03 |
[JAVA] 객체지향 프로그래밍 (0) | 2023.01.03 |