코딩테스트 하면 또 빼놓을 수 없는게 바로 해시테이블이지. 자바스크립트에서는 객체 또는 Map이 있었고, 파이썬에서는 딕셔너리가 있었다. 자바에서는 HashMap이란게 존재한다. 또한, Set에 대해서도 알아보려고 한다. 이 역시 자바스크립트와 파이썬에도 있는 개념이다.
Java에는 Map의 역할을 하는 HashMap 클래스가 존재한다. 기본적으로 put을 통해 추가할 수 있고, get을 통해 조회할 수 있다. 그 외에도 remove를 통해 제거, clear를 사용하면 초기화를 할 수 있다. 이정도만 알면 될듯?
HashMap<Integer,String> map = new HashMap<>();//new에서 타입 파라미터 생략가능
map.put(1,"사과"); //값 추가
map.put(2,"바나나");
map.put(3,"포도");
System.out.println(map.get(1));//key값 1의 value얻기 : 사과
map.remove(1); //key값 1 제거
map.clear(); //모든 값 제거
유용한 메서드 하나를 소개하자면 바로 getOrDefault 이다. 프로그래머스 "완주하지 못한 선수" 문제를 예시로 들자면, getOrDefault은 만약 키가 존재하지 않을때 값을 특정값(아래에서는 0)으로 반환해주는 녀석이다.
import java.util.*;
class Solution {
public String solution(String[] participant, String[] completion) {
String answer = "";
Map<String, Integer> hm = new HashMap<>();
for (String player : participant) {
hm.put(player, hm.getOrDefault(player, 0) + 1);
}
for (String player : completion) {
hm.put(player, hm.get(player) - 1);
}
for (String key: hm.keySet()) {
if (hm.get(key) != 0) {
answer = key;
}
}
return answer;
}
}
HashMap을 순회하는 방법으로는 entrySet과 keySet이 있다. javascript로 따지면 Object.entries, Obkect.keys 느낌이네.
//entrySet() 활용
for (Entry<Integer, String> entry : map.entrySet()) {
System.out.println("[Key]:" + entry.getKey() + " [Value]:" + entry.getValue());
}
//[Key]:1 [Value]:사과
//[Key]:2 [Value]:바나나
//[Key]:3 [Value]:포도
//KeySet() 활용
for(Integer i : map.keySet()){ //저장된 key값 확인
System.out.println("[Key]:" + i + " [Value]:" + map.get(i));
}
//[Key]:1 [Value]:사과
//[Key]:2 [Value]:바나나
//[Key]:3 [Value]:포도
만약에 키를 기준으로 해시맵을 정렬하고 싶다면 어떻게 할까? map의 keySet을 이용하여 ArrayList를 만들어 정렬한 다음, 값을 출력하는 형식으로 사용해볼 수 있다. 정렬은 Collections를 사용했다.
Map<String, Integer> map = new HashMap<>();
map.put("A", 10);
map.put("D", 30);
map.put("C", 20);
map.put("B", 40);
List<String> keySet = new ArrayList<>(map.keySet());
// 키 값으로 오름차순 정렬
Collections.sort(keySet);
for (String key : keySet) {
System.out.print("Key : " + key);
System.out.println(", Val : " + map.get(key));
}
/* 결과
Key : A, Val : 10
Key : B, Val : 40
Key : C, Val : 20
Key : D, Val : 30
*/
// 키 값으로 내림차순 정렬
Collections.reverse(keySet);
for (String key : keySet) {
System.out.print("Key : " + key);
System.out.println(", Val : " + map.get(key));
}
/* 결과
Key : D, Val : 30
Key : C, Val : 20
Key : B, Val : 40
Key : A, Val : 10
*/
이번에는 값을 기준으로 정렬하고 싶으면 어떻게 해야할까? 이번에는 좀 까다롭다. List 자체에 sort 메서드를 사용해서 그 안에 Comparator를 구현해서 정렬하는 방법과 람다 표현식 + compareTo 메서드를 통해 정렬하는 방법이 있네. (구체적인 정렬 방법에 대해서는 별도 파트에서 다룰 예정이다. )
Map<String, Integer> map = new HashMap<>();
map.put("A", 10);
map.put("D", 30);
map.put("C", 20);
map.put("B", 40);
List<String> keySet = new ArrayList<>(map.keySet());
// Value 값으로 오름차순 정렬
keySet.sort(new Comparator<String>() {
@Override
public int compare(String o1, String o2) {
return map.get(o1).compareTo(map.get(o2));
}
});
for (String key : keySet) {
System.out.print("Key : " + key);
System.out.println(", Val : " + map.get(key));
}
/*
결과
Key : A, Val : 10
Key : C, Val : 20
Key : D, Val : 30
Key : B, Val : 40
*/
// Value 값으로 내림차순 정렬
// 위 comparator 람다 표현식으로
keySet.sort((o1, o2) -> map.get(o2).compareTo(map.get(o1)));
for (String key : keySet) {
System.out.print("Key : " + key);
System.out.println(", Val : " + map.get(key));
}
/* 결과
Key : B, Val : 40
Key : D, Val : 30
Key : C, Val : 20
Key : A, Val : 10
*/