아래의 내용은 java_grammer 레파지토리 C01Basic 디렉터리에 저장되어있는 내용을 정리하였다.
Map도 List, Set처럼 인터페이스임.
주요 구현체로는 HashMap, TreeMap, LinkedHashMap이 있음.
정의 : Key, Value로 이루어진 자료구조
LinkedHashMap은 삽입 순서를 보장함 TreeMap은 Key 기준으로 정렬된 형태로 저장함 (정렬되어 있지만, 여전히 인덱스 접근은 불가능함) 이렇게 빠를 수 있는 이유는 내부에 Hash Table 구조를 사용하기 때문임.
Key를 해시 함수(Hash Function)에 통과시켜 Hash 값(16진수 난수)를 얻고, 이를 빠르게 매핑함.
예를 들어
key: 운동명, value: 해당 운동을 좋아하는 인원수
로 데이터를 저장한다고 하면,
Map<String, Integer> sports = new HashMap<>();
sports.put("농구", 2);
sports.put("축구", 3);
sports.put("배구", 2);
sports.put("농구", 3); // 기존 값 덮어쓰기
출력 결과는 아래처럼 됨 (순서가 없음):
sports : {농구=3, 배구=2, 축구=3}
특정 Key의 Value를 가져올 땐 get() 메서드를 사용함.
System.out.println("배구의 value값 : " + sports.get("배구")); // O(1)
put(key, value) → 값 추가 또는 수정
get(key) → key에 해당하는 value 반환 (복잡도 O(1))
Map은 인덱스 접근이 불가능하기 때문에,
값들을 출력하려면 keySet()이나 values()를 써야 함.
keySet() : 전체 key 목록 반환
for (String a : sports.keySet()) {
System.out.println("key : " + a + ", value : " + sports.get(a));
}
values() : 전체 value 목록 반환 (잘 쓰이진 않음)
for (int a : sports.values()) {
System.out.println("전체 value 목록 : " + a);
}
remove(key) : 특정 key 삭제
sports.remove("축구");
System.out.println("축구 삭제 : " + sports);
putIfAbsent(key, value) : key가 없을 때만 값 추가
sports.putIfAbsent("배구", 10);
System.out.println("배구=10 : " + sports);
containsKey(key) : key 존재 여부 확인
System.out.println("배구 키 있음? " + sports.containsKey("배구"));
System.out.println("탁구 키 있음? " + sports.containsKey("탁구"));
getOrDefault(key, defaultValue) :
key가 없으면 기본값을 반환
(이 메서드는 밑에 실습예제에서 자주 활용됨)
TreeMap은 key 기준으로 자동 정렬되는 Map임.
기본은 오름차순이며, Comparator를 직접 넣어서 정렬 기준을 바꿀 수 있음.
Map<String, Integer> tree_map = new TreeMap<>();
Map<String, Integer> tree_map2 = new TreeMap<>(Comparator.reverseOrder());
tree_map.put("hello5", 1);
tree_map.put("hello4", 2);
tree_map.put("hello3", 3);
tree_map.put("hello2", 4);
tree_map.put("hello1", 5);
System.out.println("TreeMap : " + tree_map);
출력은 key 순서대로 (오름차순) 나옴.
LinkedHashMap은 데이터의 삽입 순서를 보장하는 Map이다.
HashMap과 달리 입력된 순서대로 key-value를 유지한다.[1]
Map<String, Integer> linked_map = new LinkedHashMap<>();
linked_map.put("hello5", 1);
linked_map.put("hello4", 2);
linked_map.put("hello3", 3);
linked_map.put("hello2", 4);
linked_map.put("hello1", 5);
System.out.println("LinkedHashMap : " + linked_map);
// 출력: {hello5=1, hello4=2, hello3=3, hello2=4, hello1=5}
for (String a : linked_map.keySet()) {
System.out.println(linked_map.get(a));
}
주로 향상된 for문을 통해 출력하지만, Iterator를 활용한 방법도 있다.
많이 사용되지는 않으나 순회 알고리즘 이해에 유용하다.[2]
Map<String, Integer> test_map = new HashMap<>();
test_map.put("야구", 2);
test_map.put("축구", 3);
test_map.put("농구", 2);
Iterator<String> iters = test_map.keySet().iterator();
// 📍 .next() : 데이터를 하나씩 소모시키면서 값 반환
// 📍 .hasNext() : 다음 값 존재 여부 boolean 반환
while (iters.hasNext()) {
System.out.println("iters next loop : " + iters.next());
}
// test_map의 값은 소모되지 않음 (원본 보존)
주의: Iterator는 한 번 순회하면 소모되므로 재사용 시 새로 생성해야 한다.[2]
배열에 담긴 운동 종류를 Map으로 개수 세기.
String[] list_arr = {"농구", "축구", "야구", "축구", "농구", "배구"};
Map<String, Integer> like_map = new HashMap<>();
for (String a : list_arr) {
like_map.put(a, like_map.getOrDefault(a, 0) + 1);
}
System.out.println("종목별 수 : " + like_map);
출력 예시 → {야구=1, 농구=2, 배구=1, 축구=2}
like_map에서 목록에 있는 종목들을 하나씩 차감하는 로직임.
만약 count가 1이면 완전히 제거함.
String[] un_list_arr = {"농구", "농구", "농구", "야구", "축구"};
for (String a : un_list_arr) {
if (like_map.containsKey(a)) {
if (like_map.get(a) == 1) {
like_map.remove(a);
} else {
like_map.put(a, like_map.get(a) - 1);
}
}
}
System.out.println(like_map);
출력 결과 → {배구=1, 축구=1}
map에서 value가 가장 큰 key를 찾는 기본 로직임.
Map<String, Integer> max_map = new HashMap<>();
max_map.put("축구", 3);
max_map.put("농구", 2);
max_map.put("야구", 1);
int max = Integer.MIN_VALUE;
String max_key = "";
for (String a : max_map.keySet()) {
int value = max_map.get(a);
if (max < value) {
max = value;
max_key = a;
}
}
System.out.println(max_key);
출력 결과 → 축구
트리맵의 샘물