[Java] Map 기본 개념

1. Map 기본 개념

  1. Mapkeyvalue를 한 쌍으로 저장하는 구조
  2. key는 중복이 불가능하고, value는 중복이 가능
  3. key를 통해 value를 빠르게 찾을 수 있다.
  4. valuekey를 찾기는 어렵다.

2. 자주 사용하는 메서드

public class MapExample {

    public static void main(String[] args) {
        Map<String, Integer> stock = new HashMap<>();

        // put() - 값 추가
        stock.put("Apple", 150);
        stock.put("Google", 2800);
        stock.put("Amazon", 3300);

        // get() - 값 조회
        System.out.println("Apple price: " + stock.get("Apple"));

        // containsKey()
        System.out.println("Contains Tesla? " + stock.containsKey("Tesla"));

        // keySet()
        for (String company : stock.keySet()) {
            System.out.println("Company: " + company);
        }

        // values()
        for (Integer price : stock.values()) {
            System.out.println("Stock price: " + price);
        }

        // remove()
        stock.remove("Google");

        // replace()
        stock.replace("Apple", 160); // Apple 주식 가격 업데이트
    }
}
메서드 설명
toString() value를 [a, b, c…] 문자열 형태로 돌려줌
putAll(map) map을 통째로 추가
remove(K) key 제거
remove(k, v) key와 value에 해당하는 요소 제거
clear() 모든 요소 제거
isEmpty() 리스트가 비어있는지 확인
size() map 크기

3. 활용 예시

예시 1

과목, 성적을 Map으로 저장, 출력

public class SearchTest {

    public static void main(String[] args) {
        Map<String, Integer> score = new HashMap<>();
        
        score.put("국어", 90);
        score.put("수학", 85);
        score.put("영어", 90);
        score.put("사회", 80);
        score.put("과학", 100);
        System.out.println(score);
        
        score.put("사회", score.get("사회") + 5); // 성적 수정
        System.out.println(score);
        
        Scanner scan = new Scanner(System.in);
        System.out.print("조회할 과목명: "); // 과목으로 성적 찾기
        String search = scan.next();
        if (score.containsKey(search)) {
          System.out.print(search + ": " + score.get(search));
        } else {
          System.out.println("잘못 입력하셨습니다.");
        }
        
        Iterator<String> iter = score.keySet().iterator(); // 90점 이상 과목 출력
        while (iter.hasNext()) {
          String subject = iter.next();
          if (score.get(subject) >= 90) {
           System.out.print(subject + " ");
          }
        }
        System.out.println();
        
        if (score.containsValue(100)) { // 100점이 있는지 확인
          System.out.println("true");
        } else {
          System.out.println("false");
        }
    }
}

예시 2

도서명으로 작가명 찾기

public class SearchTest {

    public static void main(String[] args) {
        Map<String, Map<String, String>> bookMap = new HashMap<>();

        Map<String, String> development = new HashMap<>();
        development.put("더 해빙", "이서윤,홍주연");
        development.put("말 그릇", "김윤나");
        development.put("메모의 마법", "마에다 유지");

        Map<String, String> novel = new HashMap<>();
        novel.put("어린왕자", "생텍쥐페리");
        novel.put("아몬드", "손원평");
        novel.put("나미야 잡화점의 기적", "히가시노 게이고");
        novel.put("해변의 카프카", "무라카미 하루키");

        Map<String, String> science = new HashMap<>();
        science.put("시간은 흐르지 않는다", "카를로 로벨리");
        science.put("코스모스", "칼 세이건");
        science.put("평행우주", "미치오 카쿠");

        bookMap.put("자기계발", development);
        bookMap.put("소설", novel);
        bookMap.put("과학", science);

        Scanner scan = new Scanner(System.in);
        System.out.print("책이름을 입력해주세요: ");
        String searchBook = scan.nextLine();

        Iterator<String> iter = bookMap.keySet().iterator();
        while (iter.hasNext()) {
            String genre = iter.next();
            if (bookMap.get(genre).containsKey(searchBook)) {
              String writer = bookMap.get(genre).get(searchBook);
              System.out.println(searchBook + "의 작가명: " + writer);
              break;
            }
        }
    }
}

예시 2는 2중 Map 구조로, Map 안에 또 다른 Map을 value로 넣는 구조다.

Map<k1, Map<k2, v>> map = new HashMap<>();
  • k1: 바깥쪽 map의 key
  • k2: 안쪽 map의 key
  • v: value

다시 한번 코드를 뜯어보자.

Iterator<String> iter = bookMap.keySet().iterator();
  while (iter.hasNext()) {
    String genre = iter.next();
      if (bookMap.get(genre).containsKey(searchBook)) {
        String writer = bookMap.get(genre).get(searchBook);
        System.out.println(searchBook + "의 작가명: " + writer);
        break;
    }
  }
  1. bookMap.keySet()iter에 저장
  2. hasNext()bookMap의 key를 한번 훑어 genre에 저장
  3. bookMap.get(genre)은 bookMap 안의 Map<k2, v>을 반환
  4. containsKey로 찾고자하는 도서명의 value를 찾음

왜 굳이 다시 한번 저장하는 걸까?

가장 큰 이유는 next()는 호출할 때마다 다음 값을 가리키기 때문이다.

만약? if문의 bookMap.get(genre) 대신 bookMap.get(iter.next())을 쓴다면?

처음 자기계발은 검사하지 않고 건너뛰게 된다.

2중 Map 구조는 한번 봐서는 충분히 헷갈릴 수 있으므로 익숙해질 때까지 무한 반복할 것!!

Categories:

Updated:

Leave a comment