Java HashMap Dictionary

해쉬맵을 이용한 영한 사전 코드 과제

20182267 홍태극

전체 코드 구조

public class Main {
    public static void main(String[] args) {
        // 1. HashMap 생성
        // 2. 기본 데이터 저장
        // 3. 사용자 입력 처리
        // 4. 검색 및 결과 출력
        // 5. 프로그램 종료
    }
}

기본 클래스 구조

import java.util.*;

public class Main {
    public static void main(String[] args) {
        // 프로그램 코드
    }
}

java.util.* 임포트로 HashMap과 Scanner 사용 가능

HashMap 생성

// 영어 단어와 한글 단어의 쌍을 저장하는 HashMap 컬렉션 생성
HashMap<String, String> dic = 
    new HashMap<String, String>();
  • 키: 영어 단어 (String)
  • 값: 한글 단어 (String)

HashMap의 주요 메소드

// 데이터 추가
put(key, value)

// 데이터 검색
get(key)

// 데이터 삭제
remove(key)

// 키 존재 여부 확인
containsKey(key)

// 값 존재 여부 확인
containsValue(value)

HashMap이란?

  • 키(Key)와 값(Value) 쌍으로 데이터를 저장하는 자료구조
  • 해시 함수를 사용하여 데이터 저장 및 검색
  • 검색 속도가 매우 빠름 (O(1))
  • 순서를 유지하지 않음

해시 함수 (Hash Function)

  • 임의의 길이의 데이터를 고정된 길이의 데이터로 매핑하는 함수
  • 자바에서는 해시코드를 반환함
  • 주요 특징
    • 결정적 (같은 입력 → 항상 같은 출력)
    • 빠른 계산 가능
    • 입력 데이터가 한 글자라도 달라지면 출력이 아예 달라짐

해시 함수 예시

              graph LR
                A["입력: 'hello'"] -->|해시 함수| B["출력: 69609650"]
                C["입력: 'hello'"] -->|해시 함수| D["출력: 69609650"]
            

같은 입력은 항상 같은 출력을 생성

              graph LR
                A["입력: 'hello'"] -->|해시 함수| B["출력: 69609650"]
                C["입력: 'helle'"] -->|해시 함수| D["출력: 24563423"]
            

한 글자만 달라져도 완전히 다른 출력 생성

HashMap의 특징

  • 키(Key)의 특징
    • 고유해야 함 (중복 불가)
    • 하나의 Null값은 허용할 수 있지만 권장되지 않음
  • 값(Value)의 특징
    • 중복 가능
    • Null값은 허용할 수 있지만 권장되지 않음 (NullPointerException 발생 위험 증가)

HASHMAP의 간략한 동작 원리

            flowchart LR
              A["Key: 'apple'"] -->|"hashCode()"| B["Hash: 93029210"]
              C["Key: 'love'"] -->|"hashCode()"| D["Hash: 3327206"]
              E["Key: 'baby'"] -->|"hashCode()"| F["Hash: 2857203"]
              
              B --> |"% 16"| G["버킷[5]: '사과'"]
              D --> |"% 16"| H["버킷[10]: '사랑'"]
              F --> |"% 16"| I["버킷[3]: '아기'"]
          
  • 키의 hashCode() 메소드로 해시값 생성
  • 해시값을 버킷 크기로 나눈 나머지로 저장 위치 결정
  • 서로 다른 키가 같은 버킷 인덱스를 가질 경우 해시 충돌 발생
  • 기본 버킷 크기는 16, 자동으로 확장

해시 충돌 해결

                graph TD
                subgraph Chaining
                A["Key1: 'apple'"] -->|"hashCode() % 16"| B["버킷[4]"]
                B --> D["apple: '사과'"]
                C["Key2: 'grape'"] -->|"hashCode() % 16"| B
                D --> E["grape: '포도'"]
                end
              

체이닝

같은 버킷에 연결 리스트로 저장

                graph TD
                subgraph Open_Addressing
                F["Key1: 'apple'"] -->|"hashCode() % 16"| G["버킷[4]: apple='사과'"]
                H["Key2: 'grape'"] -->|"hashCode() % 16"| G
                G -->|"충돌! 다음 버킷으로"| I["버킷[5]: grape='포도'"]
                end
              

개방 주소법

충돌 발생 시 다음 빈 버킷을 찾아 저장

HashMap vs 일반 배열

동작 HashMap 배열
검색 O(1) O(n)
삽입 O(1) O(1)
삭제 O(1) O(n)

기본 데이터 저장

// 3 개의 (key, value) 쌍을 dic에 저장
dic.put("baby", "아기");  // "baby"는 key, "아기"은 value
dic.put("love", "사랑"); 
dic.put("apple", "사과");

저장된 데이터 구조

Key (영어) Value (한글)
baby 아기
love 사랑
apple 사과

사용자 입력 준비

// 사용자 입력을 위한 Scanner 객체 생성
Scanner scanner = new Scanner(System.in);

// 무한 루프 시작
while(true) {
    System.out.print("찾고 싶은 단어는?");
    String eng = scanner.next();

종료 조건 처리

// "exit" 입력 시 프로그램 종료
if(eng.equals("exit")) {
    System.out.println("종료합니다...");
    break;
}

equals() 메소드로 문자열 비교

  • Java에서 문자열은 == 연산자 대신 equals()를 사용
  • == 연산자는 객체의 참조를 비교
  • equals()는 문자열의 실제 내용을 비교

검색 및 결과 출력

// 해시맵에서 '키' eng의 '값' kor 검색
String kor = dic.get(eng);
if(kor == null)
    System.out.println(eng + "는 없는 단어 입니다.");
else
    System.out.println(kor);
  1. get() 메소드로 키 검색
  2. 결과가 null이면 없는 단어라고 알리는 메세지 출력
  3. 결과가 있으면 한글 단어 출력

자원 정리

// Scanner 객체 닫기
scanner.close();

프로그램 종료 전 시스템 자원 정리

전체 코드

import java.util.*;

public class Main {
    public static void main(String[] args) {
        HashMap<String, String> dic = 
            new HashMap<String, String>();
        
        dic.put("baby", "아기");
        dic.put("love", "사랑");
        dic.put("apple", "사과");
        Scanner scanner = new Scanner(System.in);
        while(true) {
            System.out.print("찾고 싶은 단어는?");
            String eng = scanner.next();
            if(eng.equals("exit")) {
                System.out.println("종료합니다...");
                break;
            }
            String kor = dic.get(eng);
            if(kor == null)
                System.out.println(eng + "는 없 단어 입니다.");
            else
                System.out.println(kor);
        }
        scanner.close();
    }
}

프로그램 실행 흐름

  1. 프로그램 시작
  2. HashMap 생성 및 기본 데이터 저장
  3. 사용자 입력 대기
  4. 입력 받은 단어 처리
    • "exit" → 프로그램 종료
    • 그 외 → 사전에서 검색
  5. 결과 출력 후 다시 입력 대기
  6. 종료 시 자원 정리