HashMap은 Java Collections Framework에 속한 구현체 클래스입니다. Java Collections Framework는 1998년 12월에 발표한 Java 2에서 정식으로 선보였습니다. Map 인터페이스 자체는 Java 5에서 Generic이 적용된 것 외에 처음 선보인 이후 변화가 없지만, HashMap 구현체는 성능을 향상시키기 위해 지속적으로 변화해 왔습니다.
개요
HashMap
과 Hashtable
은 Map인터페이스
를 상속받아 구현되어 데이터를 키와 값으로 관리하는 자료구조이다.
큰 특징으로는 키(Key)가 데이터를 추출할 때 구분자로 활용하는 방식을 취하는데 이는 리스트 인터페이스와 같은 자료구조보다 탐색에 있어 더 높은 효율을 기대할 수 있다.
공통 정의
키에 대한 해시 값을 사용하여 값을 저장하고 조회하며, 키-값 쌍의 개수에 따라 동적으로 크기가 증가하는 associate array
이 associate array를 지칭하는 다른 용어가 있는데, 대표적으로 Map, Dictionary, Symbol Table 등이다.
( 출처 :https://d2.naver.com/helloworld/831311 )
차이점
해시 충돌
- HashMap은 보조 해시 함수(Additional Hash Function)를 사용하기 때문에 보조 해시 함수를 사용하지 않는 HashTable에 비하여 해시 충돌(hash collision)이 덜 발생할 수 있어 상대으로 성능상 이점이 있다.
- 보조 해시 함수가 아니더라도, HashTable 구현에는 거의 변화가 없는 반면, HashMap은 지속적으로 개선되고 있다.
Java HashMap에서 사용하는 방식은
Separate Channing
이다.Open Addressing
은 데이터를 삭제할 때 처리가 효율적이기 어려운데, HashMap에서remove()
메서드는 매우 빈번하게 호출될 수 있기 때문이다.게다가
HashMap
에 저장된 키-값 쌍 개수가 일정 개수 이상으로 많아지면, 일반적으로Open Addressing
은Separate Chaining
보다 느리다.Open Addressing
의 경우 해시 버킷을 채운 밀도가 높아질수록 Worst Case 발생 빈도가 더 높아지기 때문이다. 반면Separate Chaining
방식의 경우 해시 충돌이 잘 발생하지 않도록 '조정'할 수 있다면 Worst Case 또는 Worst Case에 가까운 일이 발생하는 것을 줄일 수 있다.
동기화
HashMap
의 경우 동기화를 지원하지 않는다. ( Thread-Safe하지 못하다. )Collections.synchronizedMap(hashMap)
등을 이용하여 동기화 처리 후 사용해야한다.
반면 다중 스레드 환경에서HashTable
은 동기화를 지원한다. 하지만 한 자바 관련 서적에 의하면 Vector의 상위개념인 ArrayList의 사용을 권장하듯 새로운 버전인 HashMap
을 활용하고 동기화가 필요한 시점에서는 Java 5부터 제공하는 ConcurrentHashMap
을 사용하는 것이 더 좋은 방법이라 표현한다.
추가로 속도적인 측면에서도 구형이라 할 수 있는 Hashtable
은 동기화 처리라는 비용때문에HashMap
에 비해 더 느리다고 한다.
MultiThread 환경에서 동기화 처리가 필요하다면 ConcurrentHashMap을 사용하는 것이 안정적이다. 동기화가 필요하지 않은 경우라면 그냥 HashMap을 사용하자. Hashtable은 Thread-Safe 하긴 하나 느리다는 단점이 있다.
출처: https://tomining.tistory.com/169 [마이너의 일상]
반환값: iterator, enumeration
HashMap은 저장된 요소들의 순회를 위해 Fail-Fast Iterator
를 반환한다 . (ConcurrentHashMap
의 경우에는 Fail-Safe Iterator
)
HashTable은 같은 경우 Enumeration
을 반환한다.
Enumeration
과Iterator
는 컬렉션에 저장된 요소를 접근하는데 사용되는 인터페이스이다.
Enumeration
은 컬렉션 프레임워크 이전에 사용되던 인터페이스로Iterator
의 사용을 권장한다.
Iterator엔 remove()
메소드가 추가되었고 메소드 네이밍이 간략화되었다.
그리고 다른 스레드(lock된 상황에서)에서 해당 자료에 요소를 수정(삽입, 삭제, 수정 등)이 발생하면 ConcurrentModificationException
을 발생시켜 일관성을 보장한다. 이를 Fail-Fast Iterator
라 한다.
ConcurrentHashMap
의 경우 Map의 복사본을 참조하는 Iterator를 반환하며 다시 반환받은 시점에 Map에 수정이 있을 경우 해당 Iterator는 반영되지 않는다. 고로 ConcurrentModificationException
또한 발생하지 않는다. 이는 약한 일관성(Weakly Consistent)
를 제공하지만 다중 스레드상황에서 해당 Map의 무결성을 보장한다.
추가로 ListIterator가 있는데 이는 단방향만을 제공하는 Iterator의 기능을 향상시킨 것이다.
Iterator it = list.iterator();
it.next();
ListIterator li = list.listIterator();
li.next();
li.previous();
와 같이 이전을 활용할 수 있다.
다만 List 인터페이스를 상속한 컬렉션에서만 사용가능하다.
예제
HashMap
HashMap<String, Integer> map = new HashMap<String, Integer>();
map.put("a", new Integer(1));
map.put("b", new Integer(2));
map.put("c", new Integer(3));
System.out.println(map.get("a"));
System.out.println(map.get("b"));
System.out.println(map.get("c"));
해시맵과 해시테이블은 사용법이 매우 흡사하다. 선언 시 키와 값의 자료형을 선언하지 않아도 활용이 가능하다.
HashMap Iterator
HashMap<String, Integer> map = new HashMap<String, Integer>();
map.put("a", new Integer(1));
map.put("b", new Integer(2));
map.put("c", new Integer(3));
Iterator mapIt = map.keySet().iterator();
if (mapIt.hasNext()) {
System.out.println(mapIt.next());
}
Map 인터페이스를 구현한 컬렉션 클래스인 HashMap
은 키와 값이 쌍으로 저장되어 있기 때문에 iterator()
를 직접 호출하여 사용할 수 없다. 대신 keySet()
이나 entrySet()
과 같은 메서드를 활용하여 키또는 값을 따로 Set
의 형태로 얻어 온 후 다시 iterator()
를 호출하여 활용할 수 있다.
4) 참고
http://warmz.tistory.com/entry/컬렉션-프레임워크-Enumeration-Iterator-ListIterator
http://darksilber.tistory.com/entry/HashMap-HashTable-HashSet-의-차이점-외-기타
http://firedev.tistory.com/entry/Java-HashMap과-Hashtable-의-차이점
http://www.jpstory.net/2013/11/difference-hashtable-hashmap-concurrenthashmap/#iterator_vs_enumeration
https://d2.naver.com/helloworld/831311
https://odol87.tistory.com/3
https://tomining.tistory.com/169
'스프링, 자바' 카테고리의 다른 글
Dispatcher-Servlet (0) | 2021.03.04 |
---|---|
Lombok 도큐먼트 정리 (0) | 2021.03.04 |
자바의 단점 , 보일러 플레이트 (0) | 2021.02.25 |
java Reflection (0) | 2021.02.22 |
자바의 I.O (0) | 2021.02.20 |