HashMap

Java HashMap ์€ ์–ด๋–ป๊ฒŒ ๋™์ž‘ํ•˜๋Š”๊ฐ€

Java ์˜ HashMap ์€ ํ‚ค-๊ฐ’(key-value) ๊ตฌ์กฐ์˜ ์ž๋ฃŒ๊ตฌ์กฐ๋กœ, ๋‚ด๋ถ€์ ์œผ๋กœ ๋ฐฐ์—ด(Array) ๊ณผ ์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ(LinkedList), ํŠธ๋ฆฌ(Tree) ๋ฅผ ์กฐํ•ฉํ•˜์—ฌ ๊ตฌํ˜„๋˜์–ด ์žˆ์Œ.

  • ํ‰๊ท ์ ์œผ๋กœ, O(1)O(1)์˜ ์‹œ๊ฐ„ ๋ณต์žก๋„๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ์ €์žฅํ•˜๊ณ  ๊ฒ€์ƒ‰ํ•  ์ˆ˜ ์žˆ์Œ.

  • ์ค‘๋ณต๋œ ํ‚ค๋ฅผ ํ—ˆ์šฉํ•˜์ง€ ์•Š๊ณ , ๊ฐ’์€ ์ค‘๋ณต๋  ์ˆ˜ ์žˆ์Œ


1. HashMap ์˜ ๋‚ด๋ถ€ ๊ตฌ์กฐ

HashMap ์€ ๋‚ด๋ถ€์ ์œผ๋กœ ๋ฐฐ์—ด + ์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ + ํŠธ๋ฆฌ ๋กœ ๊ตฌ์„ฑ๋จ.

๊ธฐ๋ณธ์ ์ธ ์ €์žฅ ๊ตฌ์กฐ

  1. ๋ฐ์ดํ„ฐ๋ฅผ ์ €์žฅํ•  ๋•Œ, ํ•ด์‹œ ํ•จ์ˆ˜(Hash Function) ์„ ์ด์šฉํ•ด ํ‚ค๋ฅผ ํ•ด์‹œ ๊ฐ’(Hash Code) ์œผ๋กœ ๋ณ€ํ™˜

  2. ์ด ํ•ด์‹œ ๊ฐ’์„ ๊ธฐ๋ฐ˜์œผ๋กœ ๋ฐฐ์—ด์˜ ํŠน์ • ์ธ๋ฑ์Šค(Bucket) ์— ์ €์žฅ

  3. ๊ฐ™์€ ์ธ๋ฑ์Šค์— ์ถฉ๋Œ(Collision) ์ด ๋ฐœ์ƒํ•˜๋ฉด, ์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ ๋˜๋Š” ํŠธ๋ฆฌ(์ž๋ฐ” 8์ด์ƒ) ๋กœ ์ €์žฅ

HashMap<String, Integer> map = new HashMapM<();
map.put("apple", 10);
map.put("banana", 20);
map.put("cherry", 30);

์œ„ ์ฝ”๋“œ์—์„œ "apple" ์˜ ํ•ด์‹œ ๊ฐ’์ด ๋ฐฐ์—ด์˜ ํŠน์ • ์ธ๋ฑ์Šค(์˜ˆ: 5๋ฒˆ ์ธ๋ฑ์Šค ) ๋กœ ๋ณ€ํ™˜๋˜๋ฉด, ํ•ด๋‹น ์œ„์น˜์— ("apple", 10) ๊ฐ’์ด ์ €์žฅ๋จ.


2. ํ•ด์‹œ ์ถฉ๋Œ(Hash Collision) ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•

ํ•ด์‹œ ์ถฉ๋Œ์ด ๋ฐœ์ƒํ•˜๋ฉด, ๊ฐ™์€ ํ•ด์‹œ ๊ฐ’์„ ๊ฐ–๋Š” ์—ฌ๋Ÿฌ ๊ฐœ์˜ ํ‚ค๊ฐ€ ๊ฐ™์€ ๋ฒ„ํ‚ท(Index)์— ์ €์žฅ๋  ์ˆ˜ ์žˆ์Œ.

์ด ๊ฒฝ์šฐ, Java 8 ์ด์ „๊ณผ ์ดํ›„์˜ HashMap ์€ ์ถฉ๋Œ์„ ์ฒ˜๋ฆฌํ•˜๋Š” ๋ฐฉ์‹์ด ๋‹ค๋ฆ„.

๐Ÿ”ท Java 8 ์ด์ „( Linked List ์ด์šฉ)

  • ๋™์ผํ•œ ํ•ด์‹œ ๊ฐ’์ด ๋‚˜์˜ค๋ฉด, ํ•ด๋‹น ์ธ๋ฑ์Šค์˜ ์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ(Linked List) ๋์— ์ƒˆ๋กœ์šด ๋…ธ๋“œ ์ถ”๊ฐ€.

  • ์ถฉ๋Œ์ด ๋งŽ์•„์ง€๋ฉด ๊ฒ€์ƒ‰ ์„ฑ๋Šฅ์ด O(N) ๊นŒ์ง€ ๋–จ์–ด์งˆ ์ˆ˜ ์žˆ์Œ

๐Ÿ”ท Java 8 ์ดํ›„( Tree ๊ตฌ์กฐ ๋„์ž… )

  • ์ถฉ๋Œ์ด ์ผ์ • ๊ฐœ์ˆ˜(8๊ฐœ ์ด์ƒ) ์ด์ƒ ๋ฐœ์ƒํ•˜๋ฉด, ํ•ด๋‹น ๋ฒ„ํ‚ท์„ Red-Black Tree(๋ ˆ๋“œ-๋ธ”๋ž™ ํŠธ๋ฆฌ) ๋กœ ๋ณ€๊ฒฝ

  • ํŠธ๋ฆฌ ๊ตฌ์กฐ๋Š” O(log N) ์˜ ์„ฑ๋Šฅ์„ ๊ฐ€์ง€๋ฏ€๋กœ ๊ฒ€์ƒ‰ ์„ฑ๋Šฅ์ด ํ–ฅ์ƒ๋จ.

// Java 8 ์ดํ›„, ํŠธ๋ฆฌ ๋ณ€ํ™˜ ์˜ˆ์ œ 
HashMap<String, Integer> map = new HashMap<>();
for(int i = 0; i < 10; i++) {
    map.put("key" + i, i);
}

3. HashMap ์˜ ์ฃผ์š” ๋ฉ”์„œ๋“œ ๋™์ž‘ ์›๋ฆฌ

๐Ÿ”ท put(K key, V value)

  1. ํ‚ค์˜ hashCode() ๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ํ•ด์‹œ ๊ฐ’ ๊ณ„์‚ฐ

  2. ํ•ด์‹œ ๊ฐ’์— ๋”ฐ๋ผ ๋ฐฐ์—ด์˜ ์ธ๋ฑ์Šค(Bucket) ๊ฒฐ์ •

  3. ๋น„์–ด ์žˆ์œผ๋ฉด ์ƒˆ๋กœ์šด ๋…ธ๋“œ ์ถ”๊ฐ€, ์ด๋ฏธ ๊ฐ’์ด ์žˆ์œผ๋ฉด ์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ/ํŠธ๋ฆฌ์— ์ €์žฅ

map.put("dog", 100); // "dog"์˜ ํ•ด์‹œ ๊ฐ’์„ ๊ณ„์‚ฐํ•˜์—ฌ ํŠน์ • ์œ„์น˜์— ์ €์žฅ

๐Ÿ”ท get(K key)

  1. ํ‚ค์˜ hashCode() ๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ํ•ด์‹œ ๊ฐ’ ๊ณ„์‚ฐ

  2. ํ•ด๋‹น ํ•ด์‹œ ๊ฐ’์„ ๊ธฐ๋ฐ˜์œผ๋กœ ๋ฐฐ์—ด์˜ ์ธ๋ฑ์Šค๋ฅผ ์ฐพ์Œ.

  3. ํ•ด๋‹น ์ธ๋ฑ์Šค์— ํ‚ค๊ฐ€ ์กด์žฌํ•˜๋ฉด ๊ฐ’์„ ๋ฐ˜ํ™˜, ์ถฉ๋Œ์ด ์žˆ๋‹ค๋ฉด ์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ ๋˜๋Š” ํŠธ๋ฆฌ์—์„œ ๊ฒ€์ƒ‰

System.out.println(map.get("dog")); // 100

๐Ÿ”ท remove(K key)

  1. ํ‚ค์˜ ํ•ด์‹œ ๊ฐ’์„ ๊ณ„์‚ฐํ•˜์—ฌ ํ•ด๋‹น ๋ฒ„ํ‚ท์„ ์ฐพ์Œ.

  2. ํ‚ค๊ฐ€ ์กด์žฌํ•˜๋ฉด ํ•ด๋‹น ๊ฐ’์„ ์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ ๋˜๋Š” ํŠธ๋ฆฌ์—์„œ ์‚ญ์ œ

map.remove("dog");

4. HashMap ์˜ ๋™์  ํฌ๊ธฐ ์กฐ์ ˆ(Rehashing)

HashMap ์˜ ๊ธฐ๋ณธ ํฌ๊ธฐ(์ดˆ๊ธฐ ๋ฒ„ํ‚ท ์ˆ˜) ๋Š” 16 ์ด๋ฉฐ load factor(๊ธฐ๋ณธ 0.75) ๋ฅผ ์ดˆ๊ณผํ•˜๋ฉด ๋ฐฐ์—ด ํฌ๊ธฐ๋ฅผ 2๋ฐฐ๋กœ ์ฆ๊ฐ€(Resizing) ์‹œํ‚ด .

๐Ÿ”ท ๋ฆฌ์‚ฌ์ด์ง•(Resizing) ๊ณผ์ •

  1. ๋ฐฐ์—ด ํฌ๊ธฐ๊ฐ€ ๋‘ ๋ฐฐ ์ฆ๊ฐ€ (์˜ˆ: 16 โ‡’ 32)

  2. ๋ชจ๋“  ๊ธฐ์กด ํ‚ค์˜ ํ•ด์‹œ ๊ฐ’์„ ๋‹ค์‹œ ๊ณ„์‚ฐํ•˜์—ฌ ์ƒˆ๋กœ์šด ๋ฒ„ํ‚ท์— ๋ฐฐ์น˜

  3. ์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ์— ์ €์žฅ๋œ ๋…ธ๋“ฃ๋“ค๋„ ์ƒˆ๋กญ๊ฒŒ ์žฌ๋ฐฐ์น˜

HashMap<String, Integer> map = new HashMap<>(4, 0.75f); // ์ดˆ๊ธฐ ํฌ๊ธฐ 4, load factor 0.75
map.put("a",1);
map.put("b",2);
map.put("c",3);
map.put("d",4); // ์ด๋•Œ, ํฌ๊ธฐ๊ฐ€ 8๋กœ ์ฆ๊ฐ€(Rehashing ๋ฐœ์ƒ)

5. HashMap ๊ณผ HashTable ์˜ ์ฐจ์ด

๋น„๊ต ํ•ญ๋ชฉ

HashMap

Hashtable

๋™๊ธฐํ™” ์ง€์›

โŒ (๋น„๋™๊ธฐ)

โœ… (๋™๊ธฐํ™” ์ง€์›)

๋ฉ€ํ‹ฐ์Šค๋ ˆ๋“œ ํ™˜๊ฒฝ

โŒ ์Šค๋ ˆ๋“œ ์•ˆ์ „ X

โœ… ์Šค๋ ˆ๋“œ ์•ˆ์ „

์„ฑ๋Šฅ

โœ… ๋น ๋ฆ„

โŒ ๋А๋ฆผ

null ํ—ˆ์šฉ ์—ฌ๋ถ€

โœ… (null ํ‚ค/๊ฐ’ ํ—ˆ์šฉ)

โŒ (null ํ—ˆ์šฉ ์•ˆํ•จ)

๐Ÿ“Œ ๋ฉ€ํ‹ฐ์Šค๋ ˆ๋“œ ํ™˜๊ฒฝ์—์„œ๋Š” ConcurrentHashMap์„ ์‚ฌ์šฉํ•˜๋ฉด ์ข‹์Œ.

Last updated

Was this helpful?