본문 바로가기
java

Java 컬렉션 정리 for 코딩테스트 - Map

by CodingMasterLSW 2024. 12. 23.

1. Map이란?

  • key-value의 쌍을 가지는 자료구조
  • 순서를 보장하지 않음
  • 키는 중복될 수 없지만, 값은 중복될 수 있음

[ Map의 구조 ]

 

친숙한 녀석들이다. 이 그림을 어디선가 본 것 같은데... 

Set과 동일한 구조를 가지고 있다. 단지 Set은 HashSet, Map은 HashMap이다.

 

Set을 이해했다면, Map 이해는 어렵지 않을 것이다. 단지, Set 옆에 value가 추가되었을 뿐이다.

그렇기에 Map에 대한 자세한 설명을 하는 대신, Map이 어떤 메서드를 제공해주고, 어떻게 사용해야 되는지를

이번 포스팅으로 알아보자.


2. Map이 제공해주는 메서드 

Map은 key, value값으로 되어있다. 코드를 통해 살펴보자.

Map<String, Integer> studentMap = new HashMap<>();

 

key = String, value = Integer 값을 가지고 있다. 해당 Map에 값을 삽입한다면 다음과 같이 삽입할 수 있다.

studentMap.put("studentA", 90);
studentMap.put("studentB", 80);
studentMap.put("studentC", 80);
studentMap.put("studentD", 100);

 

value를 가져오려면 어떻게 해야할까?

studentMap.get("studentA");

 

위와 같이 get(key) 를 사용한다면, 해당 키에 맞는 value값을 가져올 수 있다. 

 

KeySet()

필자가 참 유용하게 쓰는 메서드이다. 모든 키 값을 반한해준다.

 

public static void main(String[] args) {
    
    Map<String, Integer> studentMap = new HashMap<>();
    studentMap.put("studentA", 90);
    studentMap.put("studentB", 80);
    studentMap.put("studentC", 80);
    studentMap.put("studentD", 100);
    System.out.println(studentMap.keySet());
}

 

해당 코드의 결과값은 [studentB, studentA, studentD, studentC] 로 나온다.

 

코드를 살펴보면 studentMap을 HashMap을 통해 구현한 것을 확인할 수 있다.

Hash 기법이 적용되어 있기에 순서가 유지되지 않는 것을 확인할 수 있다. 만약 삽입순서를 유지하고 싶다면 

LinkedHashMap을, 순서대로 정렬을 하고 싶다면 TreeMap으로 구현을 하자.

해당 구현체에 대한 설명은 Set에서 설명했기에 생략한다.

 

필자는 보통 keySet을 for-each문 돌리는데 자주 사용한다.

즉, Map에 들어있는 모든 키 값을 대상으로 작업할 때 사용한다.

 

예를 들면 다음과 같이 활용할 수 있다.

for (String key : studentMap.keySet()) {
    System.out.println("key = " + key + ", value = " + studentMap.get(key));
}

// 결과값
key = studentB, value = 80
key = studentA, value = 90
key = studentD, value = 100
key = studentC, value = 80

 

key, value값을 전부 출력해보았다. 해당 예시를 통해 keySet()에 대해 어느정도 감이 잡혔길 바란다.

 

values()

모든 value값을 반환해준다.

Collection<Integer> values = studentMap.values();
System.out.println(values);

// 결과값
[80, 90, 100, 80]

 

주의해야 할 점은, key 값의 순서가 보장되어 있지 않기 때문에 삽입 순서대로 결과값이 나오지 않는다. 

이를 유의하자. 결과값은 key와 달리 중복이 허용된다. 

key와 마찬가지로 삽입 순서대로 결과값을 도출하고 싶다면 LinkedHashMap, 정렬을 하고싶다면 TreeMap을 사용하자.

 

getOrDefault()

코딩테스트 문제를 풀 때 필자가 자주 사용하는 메서드이다.

무슨 역할을 하는 메서드이고, 어떻게 쓰이는지까지 알아보자.

public static void main(String[] args) {

    Map<String, Integer> studentMap = new HashMap<>();
    studentMap.put("studentA", 90);
    studentMap.put("studentB", 80);
    studentMap.put("studentC", 80);
    studentMap.put("studentD", 100);

    System.out.println(studentMap.getOrDefault("studentD", 0));
    System.out.println(studentMap.getOrDefault("studentE", 0));
}

// 결과값
100
0

 

키에 맞는 값이 있다면 키 값을 반환하고, 없다면 0을 반환한다.

 

필자는 해당 메서드를 해당 key 값이 몇 번 나왔는지 구할 때 자주 사용한다.

 

ex) 각 학생이 시험에 몇 번 참여했는지를 기록

public static void main(String[] args) {

    Map<String, Integer> studentMap = new HashMap<>();
    String[] studentData = {"Alice", "Bob", "Alice", "Charlie", "Alice", "Bob"};

    for (String student : studentData) {
        studentMap.put(student, studentMap.getOrDefault(student, 0) + 1);
    }

    for (String key : studentMap.keySet()) {
        System.out.println(key + ", " + studentMap.get(key));
    }
}

// 결과값
Bob, 2
Alice, 3
Charlie, 1

 

 

  • 초기값이 없다면: getOrDefault 메서드가 기본값 0을 반환하므로, 해당 키의 값을 1로 초기화.
  • 값이 이미 존재한다면: 기존 값을 가져와 +1을 더한 값을 저장.

처음보면 헷갈릴 수 있지만, 이해가 안 되면 코드를 직접 실행시키면서 이해를 해보도록 하자.

 

putIfAbsent()

없는 경우에만 입력

public static void main(String[] args) {

    Map<String, Integer> studentMap = new HashMap<>();
    studentMap.put("studentA", 80);
    studentMap.putIfAbsent("studentA", 100);
    studentMap.putIfAbsent("studentB", 100);

    System.out.println(studentMap.keySet());
    System.out.println(studentMap.values());
}
// 결과값
[studentB, studentA]
[100, 80]

 

key에 put 하려는 key값이 없을 경우에만 삽입한다. 이 또한 유용한 메서드이며, 상황에 맞게 상황해보자.


Map은 Set과 내부 동작이 매우 비슷해 주요 메서드에 대해서만 알아봤다.

Map은 정말 정말 정말 많이 쓰이는 자료구조이기 때문에... 확실하게 이해하고 넘어가면 좋을 것 같다.