프로그래밍 언어/JAVA

HashMap<K, V>

· 코딩마이데이

HashMap<K, V> 컬렉션은 경로명이 java.util.HashMap이며, '키(key)'와 '값(Value)'의 쌍으로 구성되는 요소를 다룹니다. K는 '키'로 사용할 데이터 타입을, V는 '값'으로 사용할 데이터 타입의  매개변수입니다.

해시맵은 내부에 '키'와 '값'을 저장하는 자료 구조를 가지고, 다음과 같이 put(), get() 메소드를 이용하여 요소를 삽입하거나 검색합니다.

HashMap<String, String> h = new HashMap<String, String>(); // 해시맴 생성
h.put("apple", "사과"); // "apple" 키와 "사과" 값의 쌍을 h에 삽입
String kor = h.get("apple"); // "apple" 키로 깂 검색, kor는 검색된 값, "사과"

 

put(key, value) 메서드는 '키'와 '값'을 받아, '키'를 이용하여 해시 함수(hash function)를 실행하고 해시 함수가 리턴하는 위치에 '키'와 값을 저장합니다. 반대로 get(key)은 다시 '키'를 이용하여 동일한 해시 함수를 실행하여 '값'이 저장된 위치를 일아내어 '값'을 리턴합니다. 해시맵은 해시 함수를 통해 '키'와 '값'이 저장되는 위치를 결정하므로, 사용자는 그 위치를 알 수 없고, 삽입되는 순서와 들어 있는 위치 또한 관계가 없습니다.

HashMap<String, String> 컬렉션 내부 구성과 put(), get() 메소드

 

해시맵의 장단점

해시맵은 List<E> 인터페이스를 상속받은 Vector<E>나 ArrayList<E>와는 다른 점이 있습니다.

첫째, 요소의 삽입, 삭제 시간이 매우 빠르다. 요소의 위치를 결정하는 해시 함수가 간단한 코드로 이루어지며, Vector<E>나 ArrayList<E>와 달리 요소의 삽입 삭제 시 다른 요소들의 위치 이동이 필요 없기 때문입니다.

둘째, 요소 검색은 더욱 빠릅니다. 해시먑의 get(key) 메소드가 호출되면 해시 함수가 key가 저장된 위치를 단번에 찾아내므로, Vector<E>나 ArrayList<E>에서처럼 모든 요소들을 하나의 비교하는 시간 낭비가 전혀 없기 때문입니다.

셋째, 하지만 해시맵은 인덱스를 이용하여 요소에 접근할 수 없고 오직 '키'로만 검색해야 합니다. 그러므로 해시맵은 삐른 삽입과 검색이 필요한 응용에 적합합니다.

메소드 설명
void clear() 해시맵의 모든 요소 삭제
boolean containsKey(Object key) 지정된 키(key)를 포함하고 있으면 true 리턴
boolean containsValue(Object value) 지정된 값(value)에 일치하는 키가 있으면 true 리턴
V get(Object key) 지정된 키(key)의 값 리턴, 키가 없으면 null 리턴
boolean isEmpty() 해시맵이 비어 있으면 true 리턴
Set<K> keySet() 해시맵의 모든 키를 담은 Set<K> 컬렉션 리턴
v.put(K key, V value) key와 value 쌍을 해시맵에 저장
v.remove(Object key) 지정된 키(key)를 찾아 키와 값 모두 삭제
int size() HashMap에 포함된 요소의 개수 리턴

 

해시맵 생성

해시맵은 HashMap<K, V>에서 K에는 '키'로 V에는 '값'으로 사용할 구체적인 타입을 지정하여 생성합니다.

HahMap<String, String> h = new HashMap<String, String>();
// Java 7부터 HashMap<String, String> h = new HashMap<>();로 간략히 쓸 수 있음
// Java 10부터 var h = new HashMap<String, String>();로 간략히 쓸 수 있음

 

해시맵에 요소 타입

요소를 삽입할 떄는 put() 메소드에 '키'와 '값'을 전달합니다.

k.put("baby", "아기"); // "baby"는 키, "아기"는 값
k.put("love", "사랑");
k.put("apple", "사과");

 

'키'로 값 열기

get() 메서드에 '키'를 전달하면, '값'을 얻을 수 있습니다.

String kor1 = h.get("love"); // kor1 = "사랑"

 

만일, 해시맵에 없는 '키'로 get()을 호출하면 null을 리턴합니다. 다음과 같이 "babo"라는 문자열은 현재 h에 없는 '키'이므로 get("babo")는 null을 리턴합니다.

String kor3 = h.get("babo"); // kor3 = null

 

'키'로 요소 삭제

'키'를 이용하여 요소를 삭제할 때 다음과 같이 remove() 메소드를 이용합니다.

h.remove("apple"); // put("apple", "사과")로 삽입한 요소 삭제

 

요소 개수 알아내기

요소의 개수는 다음과 같이 size() 메소드를 호출하면 됩니다.

int n = h.size(); // 현재 h 내에 있는 요소의 개수 리턴

 

HashMap<String, String> 컬렉션의 생성, 입력, 검색 등의 과정을 보여줍니다. 요소들은 해시맵에 삽입된 순서로 저장되지 않습니다.

 

해시맵의 전체 검색

해시맵에 들어 있는 요소들을 모두 알아내어 보자. 해시맵의 모든 '키'를 알아낸 후, 각 '키'에 대해 하나씩 '값'을 알아내는 방식으로 작성하면 됩니다. HashMap의 keySet() 메서드는 모든 '키'를 Set 컬렉션으로 만들어 리턴합니다.

Set<String> keys = k.keySet(); // 해시맵 h에 있는 모든 키를 Set 컬렉션으로 리턴
Iterator<String> it = keys.iterator(); // Set의 각 문자열을 순차 검색하는 Iterator 리턴
while (it.hasNext()) {
	String key = it.next(); // 키
	String value = h.get(key); // 값
	System.out.println("(" + key + "," + value + ")"); // 키와 값의 쌍 출력
}

 

HashMap<String, String> 컬렉션의 생성 및 삽입 삭제 사례

 

 

HashMap을 이용하여 (영어, 한글) 단어 쌍의 저장 검색

import java.util.HashMap;
import java.util.Scanner;

public class HashMapDicEx {
    public static void main(String[] args) {
        HashMap<String, String> dic = new HashMap<String, String>(); // 해시맵 생성
        // var = new HashMap<String, String>();로 간략히 써도 됨

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

        // 사용자로부터 영어 단어를 입력받고 한글 단어 검색. "exit" 입력받으면 종료
        Scanner scanner = new Scanner(System.in);
        while (true) {
            System.out.print("찾고 싶은 단어는?");
            String eng = scanner.next();
            if (eng.equals("exit")) {
                System.out.println("종료합니다...");
                break;
            }
            // 해시맵에서 '키' eng의 '값' kor 검색
            String kor = dic.get(eng);
            if (kor == null)
            {
                System.out.println(eng + "는 없는 단어 입니다.");
            }
            else {
                System.out.println(kor);
            }
        }
        scanner.close();
    }
}

 

실행 결과

찾고 싶은 단어는?apple
사과
찾고 싶은 단어는?babo
babo는 없는 단어 입니다.
찾고 싶은 단어는?exit
종료합니다...

 

HashMap을 이용하여 자바 과목의 이름과 점수 관리

import java.util.HashMap;
import java.util.Iterator;
import java.util.Set;

public class HashMapScoreEx {
    public static void main(String[] args) {
        // 이름과 점수를 저장할 HashMap 컬렉션 생성
        HashMap<String, Integer> scoreMap = new HashMap<String, Integer>();
        // var scoreMap = new HashMap<String, Integer>();로 간략히 써도 됨

        // 5개의 정수 저장
        scoreMap.put("김은비", 97);
        scoreMap.put("하여린", 88);
        scoreMap.put("전아린", 98);
        scoreMap.put("이동건", 70);
        scoreMap.put("양승연", 99);

        System.out.println("HashMap의 요소 개수:" + scoreMap.size());

        // 모든 사람의 점수 출력. scoreMap에 들어 있는 모든(key, value) 쌍 출력
        Set<String> keys = scoreMap.keySet(); // 모든 key를 가진 Set 컬렉션 리턴
        Iterator<String> it = keys.iterator(); // Set에 있는 key를 순서대로 검색하는 Iterator 리턴

        while (it.hasNext()) {
            String name = it.next(); // 다음 키. 학생 이름
            int score = scoreMap.get(name); // 점수 알아내기
            System.out.println(name + " : "+ score);
        }
    }
}

 

실행 결과

HashMap의 요소 개수:5
김은비 : 97
하여린 : 88
양승연 : 99
전아린 : 98
이동건 : 70

 

HashMap에 객체 저장, 학생 정보 관리

import java.util.HashMap;
import java.util.Scanner;

class Student {
    private int id;
    private String tel;
    public Student(int id, String tel) { this.id = id; this.tel = tel; }
    public int getId() { return id; }
    public String getTel() { return tel; }
}

public class HashMapStudentEx {
    public static void main(String[] args) {
        // (학생 이름, Student 객체)를 저장하는 해시맵 생성
        HashMap<String, Student> map = new HashMap<String, Student>();
        map.put("황기태", new Student(1, "010-111-1111")); // 3명의 학생 저장
        map.put("이재문", new Student(2, "010-222-2222"));
        map.put("정인환", new Student(3, "010-333-3333"));

        Scanner scanner = new Scanner(System.in);
        while (true) {
            System.out.print("검색할 이름?");
            String name = scanner.nextLine(); // 사용자로부터 이름 입력
            if (name.equals("exit"))
            {
                break; // while 문을 벗어나 프로그램 종료
            }
            Student student = map.get(name); // 이름에 해당하는 Student 객체 탐색
            if (student == null)
                System.out.println(name + "은 없는 사람입니다.");
            else
                System.out.println("id:" + student.getId() + ", 전화:" + student.getTel());
        }
        scanner.close();
    }
}

 

실행결과

검색할 이름?이재문
id:2, 전화:010-222-2222
검색할 이름?정인환
id:3, 전화:010-333-3333
검색할 이름?

 

HashMap(String, Vector<Integer>) 해시맵 응용 사례

import java.util.HashMap;
import java.util.Scanner;
import java.util.Vector;

public class ToeicScoreManager {
    public static void main(String[] args) {
        // 학생 이름과 토익 점수를 저장할 해시맵 생성(성적들은 Vector에 저장)
        HashMap<String, Vector<Integer>> map = new HashMap<String, Vector<Integer>>();
        Scanner scanner = new Scanner(System.in);

        // 해시맵에 4명 학생 저장. 성적이 저장되는 벡터는 비어 있음
        map.put("한지운", new Vector<Integer>());
        map.put("김하진", new Vector<Integer>());
        map.put("하여린", new Vector<Integer>());
        map.put("윤단비", new Vector<Integer>());

        System.out.println("등록된 학생: 한지운, 김하진, 하여린, 윤다비 등 4명입니다.");
        while (true) { // 그만이 입력될 때까지 이름과 점수 목록 입력
            System.out.print("아름과 점수들>>");
            String line = scanner.nextLine(); // 한 라인 입력(예: "윤단비 400 500 550")
            if (line.equals("그만"))
                break;
            String [] tokens = line.split(" "); // 라인을 공백으로 분리
            String name = tokens[0]; // 첫번째 토큰은 이름
            Vector<Integer> v = map.get(name); // 해시맵에서 name의 키를 가진 벡터 읽기
            if (v == null) { // 이름이 없는 경우
                System.out.println(name + "은 없는 학생입니다.");
                continue;
            }
            // 이름이 해시맵에 있는 경우 벡터 v에 정수 삽입
            for (int i = 0; i < tokens.length - 1; i++)
                v.add(Integer.parseInt(tokens[i + 1])); // 두번째 토큰부터는 점수들
        }

        while (true) { // 그만이 입력될 까지 이름으로 검색
            System.out.print("검색할 이름>>");
            String name = scanner.next(); // 한 라인 입력
            if (name.equals("그만"))
                break;
            Vector<Integer> v = map.get(name); // 이름으로 해시맵 검색. 벡터 알아냄
            if (v == null) { // 이름이 해시맵에 없는 경우
                System.out.println(name + "은 없는 학생입니다.");
                continue;
            }
            if (v.size() == 0) { // 성적이 저장된 벡터가 비어 있을 때
                System.out.println(name + "은 토익 점수가 없습니다.");
                continue;
            }
            for (int score : v)
                System.out.print(score + " ");
            System.out.println();
        }
        scanner.close();
    }
}

 

실행 결과

등록된 학생: 한지운, 김하진, 하여린, 윤다비 등 4명입니다.
아름과 점수들>>하여린 550 600 800
아름과 점수들>>김하진 570
아름과 점수들>>한지운 620
아름과 점수들>>한지윤 620
한지윤은 없는 학생입니다.
아름과 점수들>>윤단비 800 920
아름과 점수들>>김하진 700 770 880 950 980
아름과 점수들>>하여린 970
아름과 점수들>>한지운 800
아름과 점수들>>그만
검색할 이름>>김하진
570 700 770 880 950 980 
검색할 이름>>하여린
550 600 800 970 
검색할 이름>>그민
그민은 없는 학생입니다.
검색할 이름>>그만

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

'프로그래밍 언어 > JAVA' 카테고리의 다른 글

제네릭 만들기  (0) 2025.04.11
LinkedList<E> & Collections 클래스 활용  (0) 2025.04.08
컬렉션의 순차 검색을 위한 Iterator  (0) 2025.04.02
ArrrayList<E>  (0) 2025.03.30
Vector<E>  (0) 2025.03.28