Java - HashMap 정렬, 4가지 방법

자바에서 HashMap 또는 Map을 정렬(sorting)하는 다양한 방법을 소개합니다.

HashMap은 입력하는 데이터의 순서를 보장하지 않는 자료구조입니다. 그렇기 때문에 다른 자료구조를 이용하여 HashMap의 요소들을 정렬해야 합니다.

1. List를 이용하여 HashMap 정렬

keySet() 또는 values()는 HashMap에 저장된 모든 key와 value들을 List로 리턴합니다.

리스트는 순서가 있는 자료구조이기 때문에, key 또는 value에 대한 리스트를 원하는 방식으로 정렬할 수 있습니다. 만약 key 또는 value 중에 한 종류만 정렬이 필요한 경우, 이 방법을 사용하시면 됩니다.

1.1 Key로 정렬(Sort by key)

다음 코드는 key가 들어있는 List를 오름차순으로 정렬합니다.

import java.util.*;

public class Example {

    public static void main(String[] args) {

        Map<String, String> map = new HashMap<>();
        map.put("Nepal", "Kathmandu");
        map.put("United States", "Washington");
        map.put("India", "New Delhi");
        map.put("England", "London");
        map.put("Australia", "Canberra");

        List<String> keyList = new ArrayList<>(map.keySet());
        keyList.sort((s1, s2) -> s1.compareTo(s2));
        for (String key : keyList) {
            System.out.println("key: " + key + ", value: " + map.get(key));
        }
    }
}

결과

key: Australia, value: Canberra
key: England, value: London
key: India, value: New Delhi
key: Nepal, value: Kathmandu
key: United States, value: Washington

참고로, 위의 코드에서 Comparator (s1, s2)->s1.compareTo(s2)는 아래 코드처럼 메소드 레퍼런스를 사용하여String::compareTo로 대체할 수 있습니다.

keyList.sort(String::compareTo);

1.2 Value로 정렬(Sort by value)

다음 코드는 value가 들어있는 List를 오름차순으로 정렬합니다.

import java.util.*;

public class Example {

    public static void main(String[] args) {

        Map<String, String> map = new HashMap<>();
        map.put("Nepal", "Kathmandu");
        map.put("United States", "Washington");
        map.put("India", "New Delhi");
        map.put("England", "London");
        map.put("Australia", "Canberra");

        List<String> valueList = new ArrayList<>(map.values());
        valueList.sort(String::compareTo);
        for (String value : valueList) {
            System.out.println("Value: " + value);
        }
    }
}

결과

Value: Canberra
Value: Kathmandu
Value: London
Value: New Delhi
Value: Washington

2. TreeMap을 이용하여 HashMap 정렬

TreeMap은 객체를 생성할 때 인자로 Comparator를 전달할 수 있으며, 요소를 추가할 때 Comparator를 사용하여 key를 정렬하며 그 순서대로 저장이 됩니다. 즉, 데이터를 가져올 때는 이미 정렬된 순서대로 리턴이 되어 다시 정렬할 필요는 없습니다.

아래 예제에서 Comparator는 key를 오름차순으로 정렬하도록 구현하였고, 이것을 TreeMap 생성자의 인자로 전달하여 객체를 생성하였습니다.

import java.util.Comparator;
import java.util.Map;
import java.util.TreeMap;

public class Example {

    public static void main(String[] args) {

        Comparator<String> comparator = (s1, s2) -> s1.compareTo(s2);
        Map<String, String> map = new TreeMap<>(comparator);
        map.put("Nepal", "Kathmandu");
        map.put("United States", "Washington");
        map.put("India", "New Delhi");
        map.put("England", "London");
        map.put("Australia", "Canberra");

        for (Map.Entry<String, String> entry : map.entrySet()) {
            System.out.println("Key: " + entry.getKey() + ", "
                    + "Value: " + entry.getValue());
        }
    }
}

출력해보면, key가 오름차순으로 정렬되어 출력됩니다.

Key: Australia, Value: Canberra
Key: England, Value: London
Key: India, Value: New Delhi
Key: Nepal, Value: Kathmandu
Key: United States, Value: Washington

TreeMap은 value를 정렬하지는 않기 때문에 key를 정렬하는 경우에만 사용하시면 됩니다.

Comparator, Comparable 클래스 안에 요소들을 어떻게 정렬을 할 것인지에 대한 내용이 구현됩니다. 자세한 내용은 Comparator로 정렬(Sorting)하는 방법 또는 Comparable로 정렬(Sorting)하는 방법을 참고해주세요.

3. Stream을 이용하여 HashMap 정렬

Stream을 이용하여 HashMap을 정렬할 수도 있습니다.

다음 코드는 Stream을 이용하여 value 또는 key를 기준으로 정렬하는 코드입니다. Stream에서 sorted(Map.Entry.comparingByKey()) 같은 코드로 key나 value를 정렬할 수 있습니다.

import java.util.*;
import java.util.stream.Collectors;

public class Example {

    public static void main(String[] args) {

        Map<String, String> map = new HashMap<>();
        map.put("Nepal", "Kathmandu");
        map.put("United States", "Washington");
        map.put("India", "New Delhi");
        map.put("England", "London");
        map.put("Australia", "Canberra");

        // sort by key
        List<Map.Entry<String, String>> entries =
                map.entrySet().stream()
                        .sorted(Map.Entry.comparingByKey())
                        .collect(Collectors.toList());
        for (Map.Entry<String, String> entry : entries) {
            System.out.println("Key: " + entry.getKey() + ", "
                    + "Value: " + entry.getValue());
        }

        // sort by value
        System.out.println();
        entries = map.entrySet().stream()
                .sorted(Map.Entry.comparingByValue())
                .collect(Collectors.toList());
        for (Map.Entry<String, String> entry : entries) {
            System.out.println("Key: " + entry.getKey() + ", "
                    + "Value: " + entry.getValue());
        }
    }
}

결과

Key: Australia, Value: Canberra
Key: England, Value: London
Key: India, Value: New Delhi
Key: Nepal, Value: Kathmandu
Key: United States, Value: Washington

Key: Australia, Value: Canberra
Key: Nepal, Value: Kathmandu
Key: England, Value: London
Key: India, Value: New Delhi
Key: United States, Value: Washington

Stream에서 sorted()로 정렬된 아이템을 직접 출력해도 되지만 collect()로 List를 리턴하도록 했습니다.

4. LinkedHashMap을 이용하여 HashMap 정렬

LinkedHashMap는 Map에 입력한 순서가 보장되는 클래스입니다. 즉, LinkedHashMap에 입력하는 순서대로 정렬되고, 이 순서대로 데이터를 다시 꺼낼 수 있습니다. 만약 Map을 사용하고 있는데, 입력한 순서대로 Map에 저장되길 원한다면 LinkedHashMap를 사용할 수 있습니다.

번거로운 방식이지만, HashMap의 key 리스트를 정렬하고, 정렬된 순서대로 LinkedHashMap에 입력하면 입력된 순서대로 저장이 됩니다. LinkedHashMap에서 순서대로 요소를 읽으면, 정렬된 순서대로 읽을 수 있게 됩니다.

4.1 Key로 정렬(Sort by key)

Map.Entry를 리스트로 가져와 key 값으로 정렬하고, 정렬된 순서대로 LinkedHashMap에 추가하면 됩니다.

구현된 코드는 다음과 같습니다.

import java.util.*;

public class Example {

    public static LinkedHashMap<String, String> sortMapByKey(Map<String, String> map) {
        List<Map.Entry<String, String>> entries = new LinkedList<>(map.entrySet());
        Collections.sort(entries, (o1, o2) -> o1.getKey().compareTo(o2.getKey()));

        LinkedHashMap<String, String> result = new LinkedHashMap<>();
        for (Map.Entry<String, String> entry : entries) {
            result.put(entry.getKey(), entry.getValue());
        }
        return result;
    }

    public static void main(String[] args) {

        Map<String, String> map = new LinkedHashMap<>();
        map.put("Nepal", "Kathmandu");
        map.put("United States", "Washington");
        map.put("India", "New Delhi");
        map.put("England", "London");
        map.put("Australia", "Canberra");

        Map<String, String> result = sortMapByKey(map);
        for (Map.Entry<String, String> entry : result.entrySet()) {
            System.out.println("Key: " + entry.getKey() + ", "
                    + "Value: " + entry.getValue());
        }
    }
}

결과를 보면 key를 기준으로 오름차순으로 정렬되었습니다.(알파벳 순서)

Key: Australia, Value: Canberra
Key: England, Value: London
Key: India, Value: New Delhi
Key: Nepal, Value: Kathmandu
Key: United States, Value: Washington

4.2 Value로 정렬(Sort by value)

Map.Entry를 리스트로 가져와 value를 기준으로 정렬하고, 정렬된 순서대로 LinkedHashMap에 추가하면 됩니다.

구현된 코드는 다음과 같습니다.

import java.util.*;

public class Example {

    public static LinkedHashMap<String, String> sortMapByValue(Map<String, String> map) {
        List<Map.Entry<String, String>> entries = new LinkedList<>(map.entrySet());
        Collections.sort(entries, (o1, o2) -> o1.getValue().compareTo(o2.getValue()));

        LinkedHashMap<String, String> result = new LinkedHashMap<>();
        for (Map.Entry<String, String> entry : entries) {
            result.put(entry.getKey(), entry.getValue());
        }
        return result;
    }

    public static void main(String[] args) {

        Map<String, String> map = new LinkedHashMap<>();
        map.put("Nepal", "Kathmandu");
        map.put("United States", "Washington");
        map.put("India", "New Delhi");
        map.put("England", "London");
        map.put("Australia", "Canberra");

        Map<String, String> result = sortMapByValue(map);
        for (Map.Entry<String, String> entry : result.entrySet()) {
            System.out.println("Key: " + entry.getKey() + ", "
                    + "Value: " + entry.getValue());
        }
    }
}

결과를 보면 value를 기준으로 오름차순으로 정렬되었습니다.(알파벳 순서)

Key: Australia, Value: Canberra
Key: Nepal, Value: Kathmandu
Key: England, Value: London
Key: India, Value: New Delhi
Key: United States, Value: Washington

References

Loading script...
codechachaCopyright ©2019 codechacha