-
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에 포함되는 쌍들은 순서가 존재하지 않기 때문에 새로운 데이터를 생성해 그 데이터를 정렬하는 방식으로 조건 충족을 진행했다.
- Map의 entrySet을 생성하고 List로 변환한다.
- 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
'Today I Learned' 카테고리의 다른 글
WebSocket을 이용한 실시간 채팅 구현하기 3-1: 브라우저 화면을 닫을 때 퇴장 메시지 전송하기 (0) 2023.01.21 WebSocket을 이용한 실시간 채팅 구현하기 3: STOMP (0) 2023.01.21 2023년 1월 8일 (0) 2023.01.08 2023년 1월 7일 (0) 2023.01.07 2023년 1월 6일 (0) 2023.01.06