데이터 저장할 때는 키(key)값을 해싱하여 저장위치를 결정하여 값(value)을 저장한다.
특정 데이터의 저장 위치를 해시함수를 통해 알 수 있어 데이터의 추가,삭제,검색이 빠르다
Map 내부의 키(key)의 중복은 불가능 하지만 값(value)의 중복은 가능 하다.
Thread Safe 하지 않기 때문에 동시에 여러 쓰레드가 접근할 경우에 외부에서 synchronized 처리가 필요하다.
HashMap을 사용하는 이유는
key - value 쌍으로 데이터를 저장
⇒ 선형자료형과 같이 [1,2,3]이 아닌 key - value쌍 형식으로 저장하고 싶을때 사용한다.
성능
⇒ HashMap은 Hash Function을 이용하여 데이터를 삽입 검색 하기 때문에 시간복잡도 O(1)이라는 이점을 가지고 있어 사용한다.
HashMap vs HashTable
HashMap과 HashTable은 Java의 API 이름이다.
HashTable이란 JDK 1.0부터 있던 Java의 API이고, HashMap은 Java 2에서 처음 선보인 Java Collections Framework에 속한 API다.
HashTable 또한 Map 인터페이스를 구현하고 있기 때문에 HashMap과 HashTable이 제공하는 기능은 같다.
⇒ 다만 HashMap은 보조 해시 함수(Additional Hash Function)를 사용하기 때문에 보조 해시 함수를 사용하지 않는 HashTable에 비하여 해시 충돌(hash collision)이 덜 발생할 수 있어 상대으로 성능상 이점이 있다.
⇒ 보조 해시 함수가 아니더라도, HashTable 구현에는 거의 변화가 없는 반면, HashMap은 지속적으로 개선되고 있다.
⇒ HashTable의 현재 가치는 JRE 1.0, JRE 1.1 환경을 대상으로 구현한 Java 애플리케이션이 잘 동작할 수 있도록 하위 호환성을 제공하는 것에 있기 때문에, 이 둘 사이에 성능과 기능을 비교하는 것은 큰 의미가 없다고 할 수 있다.
HashMap과 HashTable 클래스의 차이점
HashTable | HashMap | |
---|---|---|
동기화 고려 | O | X |
Null 허용 | X | O |
Thread-safe 여부
⇒ Hashtable은 Thread-safe하고, HashMap은 Thread-safe하지 않다는 특징을 가지고 있다 그렇기에 멀티스레드 환경이 아니라면 Hashtable은 HashMap 보다 성능이 떨어진다는 단점을 가지고 있다.
Null 값 허용 여부
⇒ Hashtable은 key에 null을 허용하지 않지만, HashMap은 key에 null을 허용한다.
성능상 이점
⇒ HashMap은 보조해시를 사용하기 때문에 보조 해시 함수를 사용하지 않는 Hashtable에 비하여 해시 충돌(hash collision)이 덜 발생할 수 있어 상대적으로 성능상 이점이 있다.
최근까지 Hashtable은 구현에 거의 변화가 없지만, HashMap은 현재까지도 지속적으로 개선되고 있다.
충돌(collision)
이란 서로 다른 문자열이 해시 함수를 통하여 해싱한 해시값이 중복인 경우를 말한다.
충돌이 많아질수록 탐색의 시간 복잡도가 O(1)에서 -> O(n) 에 가까워지기 때문에 HashMap의 이점을 잃어버리지 않기 위한 해결할 방안이 필요하다.
충돌이 적게 나는 해시함수를 사용
충돌 발생시 충돌에 대한 해결방안 사용
Separating Chaining 동일 해시값이 있을 경우 Liked List 혹은 Red-Black tree를 통해 쇠사슬 모양으로 연결하여 관리하는 방법
장점
단점
Open addressing 데이터를 삽입하려는 버킷이 사용중이면 다른 비어 있는 버킷을 찾아 삽입하는 방법
재해싱 종류
장점
단점
HashMap 선언
//HashMap생성
HashMap<String,String> map1 = new HashMap<String,String>();
//new에서 타입 제너릭 생략가능
HashMap<String,String> map2 = new HashMap<>();
//초기 용량 지정
HashMap<String,String> map4 = new HashMap<>(10);
// 초기값 지정
HashMap<String,String> map6 = new HashMap<String,String>(){{
put("a","b");
}};
주요 메소드
메소드 | 설명 |
---|---|
containsKey(Object key) | 지정된 key가 포함되어 있는지 여부를 반환한다. |
containsValue(Object value) | 지정된 value가 포함되어 있는지 여부를 반환한다. |
entrySet() | 저장된 키와 값을 엔트리(키와 값의 결합)의 형태로 Set에 저장하여 반환한다. |
keySet() | 저장된 모든 key를 Set에 저장하여 반환한다. |
clear() | 저장된 모든 객체(key, value)를 제거한다. |
remove(Object key) | 지정된 key에 해당하는 value를 제거한다. |
getOrDefault(Object key, Object defaultValue) | 지정된 키의 값을 반환한다. 키가 없을 경우, default Value로 지정된 데이터를 반환한다. |
putAll(Map map) | Map에 저장된 모든 요소를 HashMap에 저장한다. |
replace(Object key, Object value) | 지정된 키의 값을 지정된 value로 대체한다. |
replace(Object key, Object oldValue, Object newValue) | 지정된 키와 값(oldValue)가 모두 일치하는 경우에만 새로운 값으로 대체하며, 일치 여부를 반환한다. |
get : O(1)
containsKey : O(1)
put : O(1)
remove : O(1)
next : O(h/n) h는 테이블 용량