Map을 상속받는 객체는


(1) HashTable :: (class)
(2) HashMap :: (class)
(3) LinkedHashMap :: (class)
(4) SortedMap :: (interface)
과 SortedMap을 상속받는
(5) TreeMap :: (class)
까지 포함하여 4개의 class와 1개의 interface가 있다.

모두 Map 인터페이스를 따라 
(1 Key, 1 Value) 구조로 입력/조회를 하게 된다.

각각의 객체를 순서대로 보자.

 

HashTable


- 구버전이다! (다른 애들과 달리 Java1부터 있었다.)
- HashMap과 동일한 Hash구조를 가지고 있다.
- Key와 Value에 null 값을 저장할 수 없다.
- 멀티 스레딩 개발을 할 때, Thread-safe 기능을 지원한다.

 

HashMap

 

- HashTable과 동일한 Hash구조를 가지고 있다.(ㅋ)
- Key와 Value에 null 값을 저장할 수 있다.
- 자체적으로 Thread-safe 기능을 지원하지는 않는다. (Collection 객체의 Sync 기능을 사용하여 Thread-safe하게 개발할 수 있다.)
- 저장 순서가 보장되지 않는다.(Key를 Set으로 저장하기 때문이다.)

 

LinkedHashMap

 

- HashMap과 거의 동일하다. (HashMap의 기능을 추가/변경한 확장된 객체이기 때문에 이렇게 되었다.)
- HashMap에서 Key를 Doubled Linked List(쌍방향 연결 리스트)방식으로 Key Value가 입력되는 순으로 저장하기 때문이다. (이름앞에 Linked가 붙은 이유다.)

* HashTable/HashMap/LinkedHashMap 은 몇 가지를 제외하곤 동일 인터페이스와 동일 구조를 갖기 때문에, 특별한 상황이 아니라면(Thread-safe 개발) 최신 객체인 HashMap을 추천하는 편이다.
* Hash 구조로 '선형구조'의 특징을 따라간다.(조회 시 발생하는 BigO 비용은 O(n)이다.

SortedMap

 

- 얘는 객체가 아니다. 인터페이스다(!)
- 입력받는 Key를 오름차순으로 저장하도록 형상화 되어있다.
- 왜 있을까?

 

TreeMap -> 얘 때문이다!

 

- Map이 아닌, SortedMap을 상속받는다.
- 위에서 설명한 다른 객체들과 다르게, Tree의 구조로 데이터를 관리한다.
- Tree 구조를 만들기 위해 정렬된 데이터를 필요로 하게 되었기 때문에, 데이터 정렬을 고려하지 않은 Map을 사용할 수 없기에 SortedMap 인터페이스가 만들어지고 상속받게 된 것 같다.(뇌피셜이다. 거기까지 자세하게 알고 싶지 않다.)
- Tree 구조 특성 상, 자료 조회 시의 비용은 O(n*logn)이다. 같은 이유로 데이터 입력 속도는 선형 구조인 HashMap보다 느리다.

*실무에선 사실 상 HashMap만 쓴다고 생각해도 된다.(물론 성능을 따지는 개발 또는 빡빡하게 개발하는 곳은 아닐 수 있다. 근데 그럴거면 JAVA가 아닌 성능을 우선시하는 언어를 사용할 확률이 더 높다.)


*Map객체로 데이터를 받는 경우는 대부분 정렬을 필요로 하지 않고, 대용량 데이터를 넣는 경우가 없기 때문에 자연스럽게 익숙한 HashMap을 찾게 된다.


*하지만 DB저장을 하지 않는 상황에서 대량의 데이터를 갱신 없이(주의) 유지할 일이 있다면, TreeMap을 고려해볼만은 하다.


*보통 On Memory DB를 사용하고 만다. (ex:Memcached, Redis)
-> On Memory DB는 자바 객체를 그대로 저장할 수 있기 때문에, 갱신 주기가 적은 데이터라면 TreeMap객체로 저장하면 효과를 볼 수 있을지도 모른다.



 

 

 

 

실무에서 가장 많이 사용하는 객체

단언컨데 HashMap일 것이다.
- 서비스 개발을 할 때 HashMap만 알아도 큰 걱정이 없는 것은 사실이다. 하지만 개발을 하면서 구글링을 하거나 레거시 코드(Legacy code)를 보다보면 HashTable로 대체되어 사용되는 경우를 많이 볼 수 있다. 정작 비교해보면 기능의 차이도 크게 나지 않는데 굳이 대중적인 HashMap이 아닌 HashTable을 사용해야 했을까 의문이 든다. 왜 이렇게 된 것일까?

HashMap은 언제부터?

HashMap이 포함된 Map 인터페이스는 1998년 JAVA2에서부터 지원되었고, JAVA5 이후부터 인터페이스의 변경 없이 내부 성능 향상만 있었다(JAVA8에서부터 지원된 RXJava와 Lamda 문법은 제외하고). 실무 환경도 대부분 JAVA7 이상의 버전을 사용하는 지금 시점에서는 신경 쓸 필요가 없는 사항이다.

JAVA2의 얘기는 왜 꺼내는가?

HashTable과 HashMap의 기능의 차이점Thread Safe 코딩(멀티 스레드 개발 시 데이터 일관성을 유지하는 개발) 정도인데 굳이 따로 구현된 것인지 의문을 생긴다.

 

동일한 Hash구조와 Map 인터페이스를 가지고 있는 두 객체는 같이 구현되는 것이 옳았을 것 같다. 그렇다면 '객체 단위 개발을 통한 중복 코드 제거'를 무시하고 두 번 개발된 것은 왜일까?

 

HashTable은 Map Interface가 포함된 'Java Collection Framework'가 확립되기 전, JAVA1 때 구현된 객체이기 때문이다. Java2에서 Java Collection Framework가 개발되면서 HashMap이 생겼고, Java1을 기반으로 개발된 소프트웨어들의 호환성을 위해 삭제하지 않고 남은 것으로 보인다. 

* 덕분에 HashTable은 Map 인터페이스를 상속받으면서 자바 객체 네이밍 방식인 '[자료구조][인터페이스]' (ex : Hash/Map, Tree/Map, Hash/Set) 따라 Map , Table .

*약간의 기능 차이는 있지만 HashTable과 HashMap의 모든 기능이 동일하다고 봐도 무방하다(차이나는 기능들도 다른 방식으로 동일하게 구현이 가능하다).

* HashTable을 추천하지 않거나, 실무에서 쓰지않는 것이 좋다라는 글들이 있는 것은 이러한 이유 때문이다. (추후 지원이 안되고 대체 가능한 최신 기능이 있는데 쓰기 싫은 것)

> 알고 있는 정보 및 자료를 찾아서 이해를 한 선에서 간단하게 추리긴 했지만, 더 자세한 정보가 많이 공개되어 있다.
네이버 기술 블로그 >> https://d2.naver.com/helloworld/831311

좀 많이 이론/코어로 들어가 설명이 되어있긴 하지만 이해할 시간이 있다면 언어 상관 없이 얻을 것이 많은 글이다.



 



 



 

+ Recent posts