해시맵(HashMap)

해시맵은 이름 그대로 해싱(Hashing) 된 맵(Map) 입니다.

 

해싱을 사용하기 때문에 많은 양의 데이터를 검색하는데 있어서 뛰어난 성능을 보입니다.

간단한 설명

HashMap 은 데이터를 저장할 때 키(Key) 와 밸류(Value) 가 짝을 이루어 저장됩니다.

데이터를 저장할 때는 키(Key) 값으로 해시함수를 실행한 결과를 통해 저장위치를 결정합니다.

따라서 HashMap 은 특정 데이터의 저장위치를 해시함수를 통해 바로 알 수 있기 때문에 데이터의 추가, 삭제, 특히 검색이 빠르다는 장점이 있습니다.

이러한 이유로 HashMap 은 키(Key) 값을 통해서만 검색이 가능하며, HashMap 의 키(Key) 값은 중복될 수 없고, 밸류(Value) 값은 키(Key) 값이 다르다면 중복이 가능합니다.

 

간단한 작동방식은 아래와 같습니다.

 

HashMap 생성 방법

HashMap 을 생성하려면 아래와 같이 키 타입과 값 타입을 파라미터로 주고 기본생성자를 호출합니다.

HashMap 은 저장공간보다 값이 추가로 들어오면 List 와 같이 저장공간을 추가로 늘리지만, List 와 다르게 한 칸씩 늘리지 않고 약 두배로 늘리기 때문에 여기서 과부하가 많이 발생합니다.

그렇기에 초기에 저장할 데이터 개수를 알고 있다면 Map 의 초기 용량을 지정해주는 것이 좋습니다.

// 기본 capacity : 16, load factor : 0.75
HashMap<String, String> h1 = new HashMap<String, String>(); 

// capacity : 20
HashMap<String, String> h2 = new HashMap<String, String>(20);

// capacity : 20, load factor : 0.8
HashMap<String, String> h3 = new HashMap<String, String>(20, 0.8);

// 다른 Map(h1) 의 데이터로 초기화
HashMap<String,String> h4 = new HashMap<String, String>(h1);

 

capacity 는 데이터의 저장 용량, load factor 은 데이터 저장공간을 추가로 확보해야 하는 시점을 지정합니다.

load factor 0.8 은 저장공간이 80% 채워져 있을 경우 추가로 저장공간을 확보합니다.

 

HashMap 메서드

데이터 추가

1. key 와 value 를 저장합니다.

V put(K Key, V Value)

2. Map m 의 데이터를 전부 저장합니다.

void putAll(Map<? extends K, ? extends V> m)

 

3. 기존 데이터에 만약 key 가 없다면, key 와 value 를 저장합니다.

V putIfAbsent(K key, V value)

 

예시 코드

import java.util.HashMap;
import java.util.Map;

public class MapExample {
    public static void main(String[] args) {
        // 1. put() 메서드 예시
        Map<String, String> map = new HashMap<>();
        map.put("A", "Apple");
        map.put("B", "Banana");
        map.put("C", "Cherry");

        System.out.println("After put: " + map); 
        // Output: After put: {A=Apple, B=Banana, C=Cherry}

        // 2. putAll() 메서드 예시
        Map<String, String> anotherMap = new HashMap<>();
        anotherMap.put("D", "Date");
        anotherMap.put("E", "Elderberry");
        map.putAll(anotherMap);

        System.out.println("After putAll: " + map); 
        // Output: After putAll: {A=Apple, B=Banana, C=Cherry, D=Date, E=Elderberry}

        // 3. putIfAbsent() 메서드 예시
        map.putIfAbsent("C", "Coconut"); // "C" key already exists, so this won't overwrite
        map.putIfAbsent("F", "Fig");    // "F" key doesn't exist, so it will add this entry

        System.out.println("After putIfAbsent: " + map); 
        // Output: After putIfAbsent: {A=Apple, B=Banana, C=Cherry, D=Date, E=Elderberry, F=Fig}
    }
}

 

HashMap 선언 시에 설정한 타입과 같은 타입의 Key, Value 를 넣어야 합니다.

입력하는 key 값이 이미 내부에 존재한다면 기존의 Value 는 새로 입력되는 Value 로 변경이 됩니다.

 

데이터 삭제

1. 모든 데이터를 삭제합니다.

V put(K key, V value)

2. key 와 일치하는 기존 데이터(key 와 value) 를 삭제합니다.

V remove(Object key)

3. key 와 value 가 동시에 일치하는 데이터를 삭제합니다.

V remove(K key, V value)

 

예시 코드

import java.util.HashMap;
import java.util.Map;

public class MapExample {
    public static void main(String[] args) {
        // 초기 데이터 생성
        Map<String, String> map = new HashMap<>();
        map.put("A", "Apple");
        map.put("B", "Banana");
        map.put("C", "Cherry");

        System.out.println("Initial Map: " + map); 
        // Output: Initial Map: {A=Apple, B=Banana, C=Cherry}

        // 1. remove(Object key)
        String removedValue = map.remove("B"); // "B" key를 삭제
        System.out.println("Removed value for key 'B': " + removedValue); 
        // Output: Removed value for key 'B': Banana
        System.out.println("After remove(key): " + map); 
        // Output: After remove(key): {A=Apple, C=Cherry}

        // 2. remove(Object key, Object value)
        boolean isRemoved = map.remove("C", "Coconut"); // "C" key의 value가 "Coconut"인지 확인 후 삭제
        System.out.println("Was key 'C' with value 'Coconut' removed? " + isRemoved); 
        // Output: Was key 'C' with value 'Coconut' removed? false
        System.out.println("After remove(key, value): " + map); 
        // Output: After remove(key, value): {A=Apple, C=Cherry}

        isRemoved = map.remove("C", "Cherry"); // 정확히 일치하는 key와 value 삭제
        System.out.println("Was key 'C' with value 'Cherry' removed? " + isRemoved); 
        // Output: Was key 'C' with value 'Cherry' removed? true
        System.out.println("After remove(key, value): " + map); 
        // Output: After remove(key, value): {A=Apple}

        // 3. clear()
        map.clear(); // 모든 데이터를 삭제
        System.out.println("After clear: " + map); 
        // Output: After clear: {}
    }
}

 

 

데이터 수정

1. key 와 일치하는 기존 데이터의 value 를 변경합니다.

V replace(K key, V value)

2. key 와 oldValue 가 동시에 일치하는 데이터의 value 를 new Value 로 변경합니다.

V replace(K key, V oldValue, V newValue)

 

예시 코드

import java.util.HashMap;
import java.util.Map;

public class MapReplaceExample {
    public static void main(String[] args) {
        // 초기 데이터 생성
        Map<String, String> map = new HashMap<>();
        map.put("A", "Apple");
        map.put("B", "Banana");
        map.put("C", "Cherry");

        System.out.println("Initial Map: " + map); 
        // Output: Initial Map: {A=Apple, B=Banana, C=Cherry}

        // 1. replace(K key, V value)
        String replacedValue = map.replace("B", "Blueberry"); // "B"의 값을 "Blueberry"로 변경
        System.out.println("Replaced value for key 'B': " + replacedValue); 
        // Output: Replaced value for key 'B': Banana
        System.out.println("After replace(key, value): " + map); 
        // Output: After replace(key, value): {A=Apple, B=Blueberry, C=Cherry}

        // 2. replace(K key, V oldValue, V newValue)
        boolean isReplaced = map.replace("C", "Cherry", "Coconut"); // "C"의 값이 "Cherry"일 때만 "Coconut"으로 변경
        System.out.println("Was key 'C' with value 'Cherry' replaced? " + isReplaced); 
        // Output: Was key 'C' with value 'Cherry' replaced? true
        System.out.println("After replace(key, oldValue, newValue): " + map); 
        // Output: After replace(key, oldValue, newValue): {A=Apple, B=Blueberry, C=Coconut}

        isReplaced = map.replace("A", "Avocado", "Apricot"); // "A"의 값이 "Avocado"가 아니므로 변경되지 않음
        System.out.println("Was key 'A' with value 'Avocado' replaced? " + isReplaced); 
        // Output: Was key 'A' with value 'Avocado' replaced? false
        System.out.println("After failed replace: " + map); 
        // Output: After failed replace: {A=Apple, B=Blueberry, C=Coconut}
    }
}

 

데이터 확인

1. key 와 일치하는 데이터가 있는지 여부를 반환합니다.

boolean containsKey(Object key)

2. value 가 일치하는 데이터가 있는지 여부를 반환합니다.

boolean containsValue(Object value)

3. 데이터가 빈 상태인지 여부를 반환합니다.

boolean isEmpty()

4. key-value 맵핑 데이터의 개수를 반환합니다.

int size()

 

예시 코드

import java.util.HashMap;
import java.util.Map;

public class MapUtilityMethodsExample {
    public static void main(String[] args) {
        // 초기 데이터 생성
        Map<String, String> map = new HashMap<>();
        map.put("A", "Apple");
        map.put("B", "Banana");
        map.put("C", "Cherry");

        System.out.println("Initial Map: " + map); 
        // Output: Initial Map: {A=Apple, B=Banana, C=Cherry}

        // 1. containsKey(Object key)
        boolean containsKeyA = map.containsKey("A");
        System.out.println("Does the map contain key 'A'? " + containsKeyA); 
        // Output: Does the map contain key 'A'? true

        boolean containsKeyZ = map.containsKey("Z");
        System.out.println("Does the map contain key 'Z'? " + containsKeyZ); 
        // Output: Does the map contain key 'Z'? false

        // 2. containsValue(Object value)
        boolean containsValueBanana = map.containsValue("Banana");
        System.out.println("Does the map contain value 'Banana'? " + containsValueBanana); 
        // Output: Does the map contain value 'Banana'? true

        boolean containsValueGrape = map.containsValue("Grape");
        System.out.println("Does the map contain value 'Grape'? " + containsValueGrape); 
        // Output: Does the map contain value 'Grape'? false

        // 3. isEmpty()
        boolean isMapEmpty = map.isEmpty();
        System.out.println("Is the map empty? " + isMapEmpty); 
        // Output: Is the map empty? false

        // 4. size()
        int mapSize = map.size();
        System.out.println("The size of the map: " + mapSize); 
        // Output: The size of the map: 3

        // Clear the map and check again
        map.clear();
        System.out.println("After clearing the map: " + map); 
        // Output: After clearing the map: {}

        isMapEmpty = map.isEmpty();
        System.out.println("Is the map empty after clearing? " + isMapEmpty); 
        // Output: Is the map empty after clearing? true

        mapSize = map.size();
        System.out.println("The size of the map after clearing: " + mapSize); 
        // Output: The size of the map after clearing: 0
    }
}

 

데이터 반환

1. key 와 맵핑된 value 값을 반환합니다.

V get(Object key)

2. key 와 맵핑된 value 값을 반환하고 없으면 defaultValue 값을 반환합니다.

V getOrDefault(Object key, V defaultValue)

3. 모든 key-value 맵핑 데이터를 가진 Set 데이터를 반환합니다.

Set<Map.Entry<K, V>> entrySet()

4. 모든 key 값을 가진 Set 데이터를 반환합니다

Set<K> keySet()

5. 모든 value 값을 가진 Collection 데이터를 반환합니다.

Collection<V> values()

 

예시 코드

import java.util.*;

public class MapAdvancedMethodsExample {
    public static void main(String[] args) {
        // 초기 데이터 생성
        Map<String, String> map = new HashMap<>();
        map.put("A", "Apple");
        map.put("B", "Banana");
        map.put("C", "Cherry");

        System.out.println("Initial Map: " + map); 
        // Output: Initial Map: {A=Apple, B=Banana, C=Cherry}

        // 1. get(Object key)
        String valueA = map.get("A");
        System.out.println("Value for key 'A': " + valueA); 
        // Output: Value for key 'A': Apple

        String valueZ = map.get("Z");
        System.out.println("Value for key 'Z': " + valueZ); 
        // Output: Value for key 'Z': null

        // 2. getOrDefault(Object key, V defaultValue)
        String defaultValueZ = map.getOrDefault("Z", "DefaultValue");
        System.out.println("Value for key 'Z' with default: " + defaultValueZ); 
        // Output: Value for key 'Z' with default: DefaultValue

        // 3. entrySet()
        Set<Map.Entry<String, String>> entries = map.entrySet();
        System.out.println("Entry set: " + entries); 
        // Output: Entry set: [A=Apple, B=Banana, C=Cherry]

        // 4. keySet()
        Set<String> keys = map.keySet();
        System.out.println("Key set: " + keys); 
        // Output: Key set: [A, B, C]

        // 5. values()
        Collection<String> values = map.values();
        System.out.println("Values: " + values); 
        // Output: Values: [Apple, Banana, Cherry]
    }
}

'Java' 카테고리의 다른 글

제어자  (0) 2024.12.04
로깅(Logging)  (0) 2024.11.30
MyBatis  (0) 2024.11.21
MVC구조 & Controller, Service, DAO, VO  (1) 2024.11.18
웹 서버와 WAS 의 차이  (0) 2024.11.17