Today I Learned
(24.06.11)[9주차] HashMap + 사용자 정의 Comparator 사용하기
Custom Comparator에 대해서 전에 다뤘지만, HashMap을 활용하는데 있어서 Generics 의 일치와 사용방법을 더해서 새롭게 정리를 하면서 Collection Framework의 사용을 다시 한번 더 정리하면서 학습!
HashMap + 사용자정의 Comparator 사용하기
- KODA KATA를 진행하면서 주어진 문제를 살짝 변형해서 학습할 수 있도록 HashMap 구조와 사용자 정의 Comparator를 함께 사용하여 코드를 작성하고 연습하려고 했다.
- HashMap 의 Key-Value에 관하여 Comparator에서 사용될 수 있을지 의문이 들기도 했고, 처음 코드를 작성했을때, Value를 하나씩 꺼내서 비교하고, 그 Value 에 맞는 키 값을 또 찾아서 반환하는 로직을 다시 학습하면서 수정해서 기록
public class Main {
public static void main(String[] args) {
int[] answers = {1, 2, 3, 4, 5};
int[] firstTester = {1, 2, 3, 4, 5}; //5개
int[] secondTester = {2, 1, 2, 3, 2, 4, 2, 5}; //8개
int[] thirdTester = {3, 3, 1, 1, 2, 2, 4, 4, 5, 5}; //10개
int firstCount = 0;
int secondCount = 0;
int thirdCount = 0;
for (int index = 0; index < answers.length; index++) {
int answerNumber = answers[index];
if (firstTester[index % 5] == answerNumber) {
firstCount++;
}
if (secondTester[index % 8] == answerNumber) {
secondCount++;
}
if (thirdTester[index % 10] == answerNumber) {
thirdCount++;
}
}
HashMap<String, Integer> testerMap = new HashMap<>();
testerMap.put("firstTester", firstCount);
testerMap.put("secondTester", secondCount);
testerMap.put("thirdTester", thirdCount);
ArrayList<Map.Entry<String, Integer>> testerList = new ArrayList<>(testerMap.entrySet());
Comparator<Map.Entry<String, Integer>> compareAnswer = new Comparator<Map.Entry<String, Integer>>() {
@Override
public int compare(Map.Entry<String, Integer> o1, Map.Entry<String, Integer> o2) {
return Integer.compare(o2.getValue(), o1.getValue());
}
};
Collections.sort(testerList, compareAnswer);
ArrayList<String> orderList = new ArrayList<>();
for (int index = 0; index < 3; index++) {
if (testerList.get(index).getValue() != 0) {
orderList.add(testerList.get(index).getKey());
}
}
System.out.println(orderList);
}
}
위의 문제는 3명이 일정한 패턴으로 답을 제시한다고 했을 때, answers 배열의 순서대로 3명의 답을 채점을 하고, 고득점 순서대로 리스트를 반환하는 코드
HashMap <-> List
HashMap<String, Integer> testerMap = new HashMap<>();
testerMap.put("firstTester", firstCount);
testerMap.put("secondTester", secondCount);
testerMap.put("thirdTester", thirdCount);
ArrayList<Map.Entry<String, Integer>> testerList = new ArrayList<>(testerMap.entrySet());
- HashMap은 <> 지네릭스를 통해서 key-value Pair의 각각의 타입을 지정
- HashMap 에서 Pair은 Entry
- HashMap의 put() 메서드를 통한 Entry 값 넣기
- 단, HashMap은 순서보장이 되지 않는 컬렉션이기 때문에 넣은 순서대로 나중에 ArrayList로 바꿔서 객체를 생성했을때, 순서가 잡혀버림
- ArrayList로 변환
- HashMap의 모든 Entry를 Set로 반환 -> 배열로 판단 -> ArrayList 객체로 새롭게 지정 가능
- ArrayList의 지네릭스는 HashMap의 엔트리의 Key-Value와 같아야 하고, ArrayList<<String,Integer>> 가 아니라 Map.Entry<String, Integer> 로 엔트리 째로 타입을 지정을 해줘야함
- HashMap의 entrySet() 메서드를 통해서 모든 Entry를 Set로 반환
Custom Comparator & HashMap
Comparator<Map.Entry<String, Integer>> compareAnswer = new Comparator<Map.Entry<String, Integer>>() {
@Override
public int compare(Map.Entry<String, Integer> o1, Map.Entry<String, Integer> o2) {
return Integer.compare(o2.getValue(), o1.getValue());
}
};
Collections.sort(testerList, compareAnswer);
- Custom Comparator의 타입도 역시 HashMap으로 만들어진 ArrayList 객체의 타입과 일치한 Map.Entry<String, Integer>
- @Override를 사용해서 compare하는 변수들의 타입들도 역시 Entry 이기 때문에 Map.Entry<String, Integer>
- return에서 쓰이는 변수들은 무조건 o1 o2 형태가 아니어도 됨
- 잘못 이해하고 있었던 부분 -> 가공을 할 수 있음
- return o2.getValue().compareTo(o1.getValue()); 으로 변경 가능
- Comparable 구현에서 쓰는 방식
Summary
public interface Map.Entry<K,V> {
K getKey(); // 엔트리의 키를 반환하는 메서드
V getValue(); // 엔트리의 값(value)를 반환하는 메서드
V setValue(V value); // 엔트리의 값(value)을 설정하는 메서드
}
- HashMap을 중심으로 ArrayList 외 컬렉션, Comparator 의 Generics를 사요을 해야할때, Entry 타입을 지정을 해줘야함
- 간단하게 Map.Entry<(Key 타입),(Value 타입)> 을 사용한, 일종의 Map.Entry 인터페이스의 구현체가 타입이 되는 것
'Today I Learned' 카테고리의 다른 글
(24.06.13)[9주차] Spring 심화 강의 02 (마무리) (1) | 2024.06.13 |
---|---|
(24.06.12)[9주차] Spring 심화 강의 01 (0) | 2024.06.12 |
(24.06.10)[9주차] 원시타입 Array -> List 변환 (0) | 2024.06.10 |
(24.06.07)[8주차] Spring Data의 Paging & Sort 정리 (0) | 2024.06.07 |
(24.06.05)[8주차] Response용 DTO 활용 (0) | 2024.06.05 |