** 이 포스트 에서는 Map 과 Set 에 대해 알아보도록 하겠습니다 **
Map (Java Platform SE 8 )
Set (Java Platform SE 8 )
# 핵심
Map
은 Key, Value 쌍을 가지는 오브젝트 입니다. Key는 중복될 수 없습니다.Set
은 수학 에서의 집합과 동일한 개념 입니다. 중복되지 않는 값을 갖는 오브젝트 입니다.- Map과 Set 모두 순서를 보장하지 않습니다
1 |
|
key는 Integer, value는 String인 HashMap의 play라는 변수를 만들고
1 에 조코비치, 2 에 머레이를 넣었습니다.
다시 1에 머레이를 넣게되면 나중에 들어간 머레이가 조코비치를 덮어써버려서 결국 key 1, 2의 value는 모두 “Murray”가 된것을 확인할 수 있습니다.
Set에는 값만 들어있기 때문에 4명의 플레이어의 이름을 넣고, 다섯번째에 “Djokovic”을 한번 더 넣었음에도 불구하고
중복값은 허용되지 않기 때문에 player set의 size는 여전히 4인것을 알 수 있습니다.
위의 예에서 사용한 HashMap
은 Java에서 Map Interface를 사용하는 가장 일반적인 방식 입니다.
HashMap은 동기화 되어있지 않기 때문에 동시에 여러개의 쓰레드가 동시에 값을 수정할 경우 익셉션이 발생할 수 있으니 필요한 경우 Collections.synchronizedMap
함수를 사용하거나 ConcurrentHashMap을
사용하여 이 문제를 회피할 수 있습니다.
(JDK1.5 부터 등장한 ConcurrentHashMap을 사용하는 편이 더 효율적 입니다.)
# HashMap에서 Hash는 무슨 역할을 하는가
네이버의 helloworld 블로그에 자세한 동작방식이 설명되어 있으니 궁금하신분들은 한번씩 읽어보시면 도움이 될것 같습니다.
요약해서 쉽게 설명을 해 보면
HashMap은 key-value 페어를 담을수 있는 buckets을 가지고 있습니다.
put(key,value)메소드를 호출하면 각 key-value 페어가 어느 bucket에 들어갈지 결정할때 바로 hashCode()함수가 사용 됩니다.
get(key)를 호출한 경우에도 어느 bucket에서 데이터를 가져올지 결정할때 hashCode()가 사용 됩니다.
(내부적으로 이 hashcode의 리턴값으로 shift 연산을 통해 결정된다고 하네요)
어느 bucket인지 알았으면 실제 그버킷에 들어있는 모든 키의 hashcode 값끼리 equals()를 통해 원하는 put이나 get 의 결과를 얻을 수 있게 됩니다.
# +@ HashMap VS HashTable
- Hashtable은 synchronized, HashMap 은 아님
- Hashtable 은 null을 key나 value로 가질수 없음, Hashmap은 하나의 null key와 여러개의 null 값을 가질 수 있음
- Hashmap을 사용하다가 순서가 중요해 진 경우 단순히 Hashmap의 선언부를 LinkedHashMap으로 변경해주면 나머지 코드는 건드릴 필요가 없으나 Hashtable로 하려면 골치가 아파짐.