ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Java에서 단일 Key, Value 쌍 사용하기: Map.Entry<K, V>
    Today I Learned 2023. 1. 20. 01:24

    프로그래머스 레벨 3 해시 문제 '베스트앨범'을 풀면서 사용한 Map.Entry<K, V> Interface에 대해 정리했다.

     

    Map.Entry<K, V>

    Map<K, V> 타입의 인터페이스를 구현한 구현체에 대해 entrySet() 메서드를 호출하는 경우, 구현체에 포함되어 있는 [Key, Value] 쌍 전체를 포함하는 Set 컬렉션을 반환받을 수 있다.

    Map<String, Integer> genresAndPlaySums = Map.of(
        "jazz", 1200,
        "classic", 5000,
        "k-pop", 2500,
        "j-pop", 300
    );
    
    Set<Map.Entry<String, Integer>> entries = genresAndPlaySums.entrySet();

     

    cf. docs.oracle.com에 따르면, 이렇게 얻은 Map.Entry<K, V>들은 해당 Map의 항목에 대한 참조로써 사용될 수 있다고 한다.

    Map<String, Integer> map = new HashMap<>();
    map.put("text1", 1234);
    
    List<Map.Entry<String, Integer>> entries = map.entrySet()
        .stream()
        .toList();
    entries.get(0).setValue(9999);
    System.out.println(map.get("text1"));	// 9999

     

    혹은 Map.Entry<K, V>의 구현체인 AbstractMap.SimpleEntry<K, V>의 생성자를 이용해 직접 생성할 수도 있다. 

    List<Map.Entry<Integer, Integer>> indicesAndPlays = List.of(
        new AbstractMap.SimpleEntry<>(2, 100),
        new AbstractMap.SimpleEntry<>(0, 2000),
        new AbstractMap.SimpleEntry<>(1, 200),
        new AbstractMap.SimpleEntry<>(3, 1750)
    );

     

    Map.Entry<K, V>의 각 요소들에 대해서는 getKey(), getValue() 메서드로 접근할 수 있다.

    Map.Entry<String, Integer> entry = new AbstractMap.SimpleEntry<>("text1", 4444);
    System.out.println(entry.getKey());	// text1
    System.out.println(entry.getValue());	// 4444

     

    Map.Entry<K, V> 활용 예시: Map의 요소들을 [Key, Value] 쌍을 유지한 채로 Key나 Value에 따라 정렬하기

    '베스트앨범' 문제의 풀이 조건들 중 다음의 조건이 있다.

    속한 노래가 많이 재생된 장르를 먼저 수록합니다.

     

    문제의 데이터로 주어지는 index에 해당하는 노래의 장르가 명시된 배열 genres와 노래의 재생 횟수가 명시된 배열 plays를 이용해 Map<장르, 재생 횟수의 합>을 정의하고, 각 Key에 해당하는 장르의 Value에 각 노래의 재생 횟수를 더해서 장르별 재생 횟수의 합을 생성했다고 할 때, Map의 쌍을 Value가 큰 순서대로 내림차순 정렬해서 조건을 만족하는 데이터를 생성할 수 있을 것이다.

    장르별 재생 횟수의 합을 생성했다고 가정할 때, Map.Entry를 이용해서 Map에 포함된 쌍들을 Value의 내림차순으로 정렬해본 예시는 다음과 같다. HashMap에 포함되는 쌍들은 순서가 존재하지 않기 때문에 새로운 데이터를 생성해 그 데이터를 정렬하는 방식으로 조건 충족을 진행했다.

     

    1. Map의 entrySet을 생성하고 List로 변환한다.
    2. List의 각 요소인 Map.Entry의 Value 값을 비교하면서 List를 정렬한다.
    Map<String, Integer> genresAndPlaySums = Map.of(
        "jazz", 1200,
        "classic", 5000,
        "k-pop", 2500,
        "j-pop", 300
    );
    
    List<Map.Entry<String, Integer>> genresAndPlaySumsDescending
    	= genresAndPlaySums.entrySet().stream()
            .sorted((previous, next) -> (
                next.getValue().compareTo(previous.getValue())
            ))
            .toList();
    
    System.out.println(genresAndPlaySumsDescending.get(0).getKey());
    	// classic
    System.out.println(genresAndPlaySumsDescending.get(1).getKey());
    	// k-pop
    System.out.println(genresAndPlaySumsDescending.get(2).getKey());
    	// jazz
    System.out.println(genresAndPlaySumsDescending.get(3).getKey());
    	// j-pop

     

    References

    - https://docs.oracle.com/javase/8/docs/api/java/util/Map.Entry.html

    - https://docs.oracle.com/javase/8/docs/api/java/util/AbstractMap.SimpleEntry.html

    - https://recordsoflife.tistory.com/314

     

     

     

     

    댓글

Designed by Tistory.