[JAVA] HashMap을 키(key), 값(value) 기준으로 정렬하는 방법

2023. 1. 6. 01:03Java

 

백준 1339 단어 수학 문제를 풀다가 HashMap을 Value 기준으로 정렬하고자 HashMap 정렬에 대해 찾아보게 되었다.

HashMap은 키와 값 기준으로 정렬이 가능한데, 그 방법에 대해 알아보자.

 

 

 

HashMap이란

출처 -https://keepmind.net/java-collection-framework-4/

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