๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ

๋นˆ ๊ตฌ๋ฉ ์ฑ„์šฐ๊ธฐ

[Java] NavigableMap

์ถœ์ฒ˜

ChatGPT


NavigableMap์€ ์ž๋ฐ” ์ปฌ๋ ‰์…˜ ํ”„๋ ˆ์ž„์›Œํฌ์—์„œ ์ •๋ ฌ๋œ ํ‚ค-๊ฐ’ ์Œ์„ ์ €์žฅํ•˜๊ณ , ์–‘๋ฐฉํ–ฅ ํƒ์ƒ‰ ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•˜๋Š” ์ธํ„ฐํŽ˜์ด์Šค์ด๋‹ค. NavigableMap์€ SortedMap ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ํ™•์žฅํ•˜์—ฌ, ์ƒ์œ„ ๋˜๋Š” ํ•˜์œ„ ๊ฐ’์„ ์ฐพ๊ณ  ์„œ๋ธŒ๋งต์„ ์ƒ์„ฑํ•˜๋Š” ๋“ฑ, ๋” ๋งŽ์€ ํƒ์ƒ‰ ๊ด€๋ จ ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•œ๋‹ค.

 

1. NavigableMap์˜ ์ฃผ์š” ํŠน์ง•

์ •๋ ฌ๋œ ๋งต

NavigableMap์€ ํ‚ค๊ฐ€ ํ•ญ์ƒ ์ •๋ ฌ๋œ ์ˆœ์„œ๋กœ ์ €์žฅ๋œ๋‹ค. ๊ธฐ๋ณธ์ ์œผ๋กœ ์ž์—ฐ ์ˆœ์„œ(Natural Ordering)์— ๋”ฐ๋ผ ์ •๋ ฌ๋˜์ง€๋งŒ, ์‚ฌ์šฉ์ž๊ฐ€ ์ œ๊ณตํ•œ Comparator๋ฅผ ํ†ตํ•ด ์‚ฌ์šฉ์ž ์ •์˜ ์ˆœ์„œ๋กœ ์ •๋ ฌํ•  ์ˆ˜๋„ ์žˆ๋‹ค.

์–‘๋ฐฉํ–ฅ ํƒ์ƒ‰

NavigableMap์€ ํ‚ค์™€ ๊ฐ’์„ ๊ธฐ์ค€์œผ๋กœ ์ƒ์œ„ ๋˜๋Š” ํ•˜์œ„ ๋ฐฉํ–ฅ์œผ๋กœ ํƒ์ƒ‰ํ•  ์ˆ˜ ์žˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ๊ฐ€์žฅ ๊ฐ€๊นŒ์šด ์ƒ์œ„ ํ‚ค๋‚˜ ํ•˜์œ„ ํ‚ค๋ฅผ ์ฐพ๋Š” ๋ฉ”์„œ๋“œ๋ฅผ ์ œ๊ณตํ•œ๋‹ค.

์„œ๋ธŒ๋งต ์ƒ์„ฑ

ํ‚ค์˜ ๋ฒ”์œ„๋ฅผ ์ง€์ •ํ•ด ์„œ๋ธŒ๋งต์„ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด ํŠน์ • ๊ตฌ๊ฐ„์— ์†ํ•œ ํ‚ค-๊ฐ’ ์Œ๋“ค๋งŒ์„ ํฌํ•จํ•˜๋Š” ๋ถ€๋ถ„ ๋งต์„ ์–ป์„ ์ˆ˜ ์žˆ๋‹ค.

 

2. NavigableMap์„ ๊ตฌํ˜„ํ•œ ํด๋ž˜์Šค

TreeMap 

NavigableMap ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๊ตฌํ˜„ํ•œ ๋Œ€ํ‘œ์ ์ธ ํด๋ž˜์Šค์ด๋‹ค. TreeMap์€ ๋‚ด๋ถ€์ ์œผ๋กœ ๋ ˆ๋“œ-๋ธ”๋ž™ ํŠธ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•ด ์ •๋ ฌ๋œ ๋งต์„ ๊ตฌํ˜„ํ•œ๋‹ค.

 

3. NavigableMap์˜ ์ฃผ์š” ๋ฉ”์†Œ๋“œ

1. ๋ฒ”์œ„ ํƒ์ƒ‰ ๋ฉ”์†Œ๋“œ

lowerEntry(K key)

์ฃผ์–ด์ง„ ํ‚ค๋ณด๋‹ค ์ž‘์€, ๊ฐ€์žฅ ํฐ ํ‚ค-๊ฐ’ ์Œ์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค. ํ‚ค๊ฐ€ ์—†๋‹ค๋ฉด null์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค.

floorEntry(K key)

์ฃผ์–ด์ง„ ํ‚ค์™€ ๊ฐ™์€ ๊ฐ’์ด๊ฑฐ๋‚˜, ์ž‘์€ ํ‚ค-๊ฐ’ ์Œ๋“ค ์ค‘ ๊ฐ€์žฅ ํฐ ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค. 

ceilingEntry(K key)

์ฃผ์–ด์ง„ ํ‚ค๋ณด๋‹ค ๊ฐ™์€ ๊ฐ’์ด๊ฑฐ๋‚˜, ํฐ ํ‚ค-๊ฐ’ ์Œ๋“ค ์ค‘ ๊ฐ€์žฅ ์ž‘์€ ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค.

highterEntry(K key)

์ฃผ์–ด์ง„ ํ‚ค๋ณด๋‹ค ์ž‘์€ ํ‚ค-๊ฐ’ ์Œ์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค.

 

 

์ด ๋ฉ”์†Œ๋“œ๋“ค์€ ์–‘๋ฐฉํ–ฅ ํƒ์ƒ‰์„ ์ง€์›ํ•˜๋Š” ์ฃผ์š” ๋ฉ”์†Œ๋“œ๋“ค๋กœ, ํŠน์ • ํ‚ค์— ๋Œ€ํ•ด ์ƒ์œ„ ๋˜๋Š” ํ•˜์œ„ ๋ฐฉํ–ฅ์œผ๋กœ ๊ฐ€์žฅ ๊ฐ€๊นŒ์šด ํ‚ค๋ฅผ ์ฐพ๋Š” ๋ฐ ์‚ฌ์šฉ๋œ๋‹ค.

2. ์„œ๋ธŒ๋งต ๋ฉ”์†Œ๋“œ

subMap(K fromKey, boolean fromInclusive, K toKey, boolean toInclusiive)

์ฃผ์–ด์ง„ ๋ฒ”์œ„ ์•ˆ์— ํฌํ•จ๋œ ํ‚ค-๊ฐ’ ์Œ์œผ๋กœ ์ด๋ฃจ์–ด์ง„ ์„œ๋ธŒ๋งต์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค.

headMap(K toKey, boolean inclusive)

์ฃผ์–ด์ง„ ํ‚ค๋ณด๋‹ค ์ž‘์€ ํ‚ค-๊ฐ’ ์Œ์„ ํฌํ•จํ•˜๋Š” ์„œ๋ธŒ๋งต์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค.

tailMap(K fromKey, boolean inclusive)

์ฃผ์–ด์ง„ ํ‚ค๋ณด๋‹ค ํฐ ํ‚ค-๊ฐ’ ์Œ์„ ํฌํ•จํ•˜๋Š” ์„œ๋ธŒ๋งต์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค.

 

 

์„œ๋ธŒ๋งต ๋ฉ”์†Œ๋“œ๋Š” ํŠน์ • ๋ฒ”์œ„์— ์†ํ•œ ์š”์†Œ๋“ค๋งŒ์„ ๊ฐ€์ ธ์˜ค๋Š” ๋ฐ ์œ ์šฉํ•˜๋‹ค. ์ด ๋ฉ”์†Œ๋“œ๋“ค์€ ๋ฒ”์œ„ ๊ธฐ๋ฐ˜ ์กฐํšŒ๋ฅผ ๊ฐ€๋Šฅํ•˜๊ฒŒ ํ•œ๋‹ค.

3. ๋‚ด๋ฆผ์ฐจ์ˆœ ์ •๋ ฌ ๋ฉ”์†Œ๋“œ

descendingMap()

๋งต์˜ ํ‚ค-๊ฐ’ ์Œ์„ ๋‚ด๋ฆผ์ฐจ์ˆœ์œผ๋กœ ์ •๋ ฌํ•œ ์ƒˆ๋กœ์šด ๋งต์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค.

descendingKeySet()

ํ‚ค๋งŒ ๋‚ด๋ฆผ์ฐจ์ˆœ์œผ๋กœ ์ •๋ ฌํ•œ navigableSet์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค.

 

 

descendingMap()์„ ์‚ฌ์šฉํ•˜๋ฉด NavigalbeMap์„ ๋‚ด๋ฆผ์ฐจ์ˆœ์œผ๋กœ ์ •๋ ฌ๋œ ์ƒˆ๋กœ์šด ๋งต์œผ๋กœ ๋ณ€ํ™˜ํ•  ์ˆ˜ ์žˆ๋‹ค. ์›๋ž˜์˜ ๋งต์—๋Š” ์˜ํ–ฅ์„ ๋ฏธ์น˜์ง€ ์•Š๊ณ , ๋‚ด๋ฆผ์ฐจ์ˆœ์œผ๋กœ ์ˆœํšŒํ•  ์ˆ˜ ์žˆ๋‹ค.

4. ๊ธฐํƒ€ ๋ฉ”์†Œ๋“œ

pollFirstEntry()

๋งต์˜ ์ฒซ ๋ฒˆ์งธ(๊ฐ€์žฅ ์ž‘์€ ํ‚ค-๊ฐ’ ์Œ)๋ฅผ ์ œ๊ฑฐํ•˜๊ณ  ๋ฐ˜ํ™˜ํ•œ๋‹ค.

pollLastEntry()

๋งต์˜ ๋งˆ์ง€๋ง‰(๊ฐ€์žฅ ํฐ ํ‚ค-๊ฐ’ ์Œ)์„ ์ œ๊ฑฐํ•˜๊ณ  ๋ฐ˜ํ™˜ํ•œ๋‹ค.

 

 

์ด ๋ฉ”์†Œ๋“œ๋“ค์€ ๊ฐ€์žฅ ์ž‘๊ฑฐ๋‚˜ ๊ฐ€์žฅ ํฐ ์š”์†Œ๋ฅผ ์ œ๊ฑฐํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋œ๋‹ค. ์ด๋Š” ํ์˜ ์ž‘์—…์ฒ˜๋Ÿผ ๋™์ž‘ํ•˜๋ฉฐ, ์ œ๊ฑฐ๋œ ํ‚ค-๊ฐ’ ์Œ์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค.

 

4. NavigableMap์˜ ์ฃผ์š” ๋ฉ”์†Œ๋“œ ์‚ฌ์šฉ ์˜ˆ์‹œ

๋‹ค์Œ์€ TreeMap์„ ์‚ฌ์šฉํ•ด NavigableMap์˜ ์ฃผ์š” ๋ฉ”์†Œ๋“œ๋“ค์„ ์‚ฌ์šฉํ•˜๋Š” ์˜ˆ์‹œ์ด๋‹ค.

import java.util.*;

public class NavigableMapExample {
    public static void main(String[] args) {
        NavigableMap<String, Integer> treeMap = new TreeMap<>();
        
        // TreeMap์— ์š”์†Œ ์ถ”๊ฐ€
        treeMap.put("apple", 10);
        treeMap.put("banana", 20);
        treeMap.put("cherry", 30);
        treeMap.put("date", 40);
        treeMap.put("elderberry", 50);

        // ์ƒ์œ„/ํ•˜์œ„ ํƒ์ƒ‰ ๋ฉ”์„œ๋“œ ์˜ˆ์‹œ
        System.out.println("Lower entry than 'cherry': " + treeMap.lowerEntry("cherry"));
        System.out.println("Floor entry for 'cherry': " + treeMap.floorEntry("cherry"));
        System.out.println("Ceiling entry for 'cherry': " + treeMap.ceilingEntry("cherry"));
        System.out.println("Higher entry than 'cherry': " + treeMap.higherEntry("cherry"));

        // ์„œ๋ธŒ๋งต ์˜ˆ์‹œ
        NavigableMap<String, Integer> subMap = treeMap.subMap("banana", true, "date", true);
        System.out.println("\nSubMap from 'banana' to 'date': " + subMap);

        // ๋‚ด๋ฆผ์ฐจ์ˆœ ๋งต ์˜ˆ์‹œ
        NavigableMap<String, Integer> descendingMap = treeMap.descendingMap();
        System.out.println("\nDescending Map: " + descendingMap);

        // ์ฒซ ๋ฒˆ์งธ์™€ ๋งˆ์ง€๋ง‰ ์š”์†Œ ์ œ๊ฑฐ
        Map.Entry<String, Integer> firstEntry = treeMap.pollFirstEntry();
        System.out.println("\nFirst entry removed: " + firstEntry);
        Map.Entry<String, Integer> lastEntry = treeMap.pollLastEntry();
        System.out.println("Last entry removed: " + lastEntry);

        // ํ˜„์žฌ TreeMap ์ƒํƒœ
        System.out.println("\nCurrent TreeMap: " + treeMap);
    }
}

 

์ถœ๋ ฅ ๊ฒฐ๊ณผ

Lower entry than 'cherry': banana=20
Floor entry for 'cherry': cherry=30
Ceiling entry for 'cherry': cherry=30
Higher entry than 'cherry': date=40

SubMap from 'banana' to 'date': {banana=20, cherry=30, date=40}

Descending Map: {elderberry=50, date=40, cherry=30, banana=20, apple=10}

First entry removed: apple=10
Last entry removed: elderberry=50

Current TreeMap: {banana=20, cherry=30, date=40}

 

5. NavigableMap์˜ ํƒ์ƒ‰๊ณผ ์„œ๋ธŒ๋งต ๊ธฐ๋Šฅ

NavigableMap์˜ ๊ฐ€์žฅ ํฐ ์žฅ์ ์€ ์–‘๋ฐฉํ–ฅ ํƒ์ƒ‰๊ณผ ์„œ๋ธŒ๋งต ๊ธฐ๋Šฅ์ด๋‹ค.

  • ์–‘๋ฐฉํ–ฅ ํƒ์ƒ‰์€ ์ƒ์œ„ ๋˜๋Š” ํ•˜์œ„ ํ‚ค๋ฅผ ์ฐพ๊ณ , ๋ฒ”์œ„๋ฅผ ์„ค์ •ํ•ด ์กฐํšŒํ•˜๋Š” ๋ฐ ๋งค์šฐ ์œ ์šฉํ•˜๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ํŠน์ • ํ‚ค๋ณด๋‹ค ์ž‘๊ฑฐ๋‚˜ ๊ฐ™์€ ๊ฐ’, ํ˜น์€ ํฐ ๊ฐ’๋“ค์„ ์‰ฝ๊ฒŒ ์ฐพ์„ ์ˆ˜ ์žˆ๋‹ค.
  • ์„œ๋ธŒ๋งต ๊ธฐ๋Šฅ์€ ํŠน์ • ๋ฒ”์œ„์— ํ•ด๋‹นํ•˜๋Š” ํ‚ค-๊ฐ’ ์Œ๋“ค์„ ์‰ฝ๊ฒŒ ์ถ”์ถœํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, ์ด๋ฅผ ํ†ตํ•ด ๋ฒ”์œ„ ๊ธฐ๋ฐ˜ ์กฐํšŒ๋‚˜ ์ž‘์—…์„ ํšจ์œจ์ ์œผ๋กœ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ๋‹ค.

 

6. NavigableMap์„ ํ™œ์šฉํ•˜๋Š” ๊ฒฝ์šฐ

1. ๋ฒ”์œ„ ๊ธฐ๋ฐ˜ ํƒ์ƒ‰

NavigableMap์€ ํ‚ค ๊ฐ’์˜ ๋ฒ”์œ„๊ฐ€ ์ค‘์š”ํ•œ ๊ฒฝ์šฐ์— ์œ ์šฉํ•˜๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ๋‚ ์งœ๋ฅผ ํ‚ค๋กœ ์‚ฌ์šฉํ•ด ์ผ์ • ๋ฒ”์œ„์˜ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜ค๋Š” ๋“ฑ์˜ ์ž‘์—…์— ์ ํ•ฉํ•˜๋‹ค.

2. ์ •๋ ฌ๋œ ๋ฐ์ดํ„ฐ ๊ด€๋ฆฌ

ํ‚ค๊ฐ€ ํ•ญ์ƒ ์ •๋ ฌ๋œ ์ƒํƒœ๋ฅผ ์œ ์ง€ํ•ด์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ์— ์œ ์šฉํ•˜๋‹ค. ์ด๋ฅผ ํ†ตํ•ด ๋ฐ์ดํ„ฐ๋ฅผ ์ •๋ ฌ๋œ ์ˆœ์„œ๋กœ ์กฐํšŒํ•˜๊ฑฐ๋‚˜ ํŠน์ • ๊ตฌ๊ฐ„์˜ ๋ฐ์ดํ„ฐ๋งŒ ํšจ์œจ์ ์œผ๋กœ ๋‹ค๋ฃฐ ์ˆ˜ ์žˆ๋‹ค.

3. ์šฐ์„ ์ˆœ์œ„ ๊ธฐ๋ฐ˜ ๋ฐ์ดํ„ฐ ๊ด€๋ฆฌ

๋‚ด๋ฆผ์ฐจ์ˆœ ๋˜๋Š” ํŠน์ • ์ˆœ์„œ๋ฅผ ์œ ์ง€ํ•˜๋ฉฐ ๋ฐ์ดํ„ฐ๋ฅผ ๊ด€๋ฆฌํ•˜๋Š” ๋ฐ ์œ ์šฉํ•˜๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ์šฐ์„ ์ˆœ์œ„๊ฐ€ ๋†’์€ ์ž‘์—…์„ ๋จผ์ € ์ฒ˜๋ฆฌํ•˜๋Š” ํ๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

 

7. NavigableMap๊ณผ SortedMap์˜ ์ฐจ์ด์ 

NavigableMap์€ SortedMap์˜ ํ™•์žฅํ˜•์œผ๋กœ, ์ถ”๊ฐ€์ ์ธ ํƒ์ƒ‰ ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•œ๋‹ค. SortedMap์€ ๊ธฐ๋ณธ์ ์ธ ์ •๋ ฌ๊ณผ ์„œ๋ธŒ๋งต ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•˜์ง€๋งŒ, NavigableMap์€ ์ƒ์œ„/ํ•˜์œ„ ํƒ์ƒ‰, ๋‚ด๋ฆผ์ฐจ์ˆœ ์กฐํšŒ, ์ฒซ ๋ฒˆ์งธ/๋งˆ์ง€๋ง‰ ํ•ญ๋ชฉ ์ œ๊ฑฐ์™€ ๊ฐ™์€ ๋” ๋งŽ์€ ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•œ๋‹ค.

ํŠน์ง• SortedMap NavigableMap
์ •๋ ฌ ํ‚ค๊ฐ€ ํ•ญ์ƒ ์ •๋ ฌ๋œ ์ƒํƒœ ํ‚ค๊ฐ€ ํ•ญ์ƒ ์ •๋ ฌ๋œ ์ƒํƒœ
์„œ๋ธŒ๋งต ๊ธฐ๋Šฅ ์„œ๋ธŒ๋งต ์ œ๊ณต ์„œ๋ธŒ๋งต ์ œ๊ณต
์ƒ/ํ•˜ ํƒ์ƒ‰ ์ œ๊ณต ์•ˆ ํ•จ lower(), floor(), ceiling(), higher() ์ œ๊ณต
๋‚ด๋ฆผ์ฐจ์ˆœ ๋งต ์ œ๊ณต ์•ˆ ํ•จ descendingMap() ์ œ๊ณต
์š”์†Œ ์ œ๊ฑฐ ์ œ๊ณต ์•ˆ ํ•จ pollFirstEntry(), pollLastEntry() ์ œ๊ณต

 

 

8. ๊ฒฐ๋ก 

NavigableMap์€ ์ •๋ ฌ๋œ ๋งต์˜ ๊ธฐ๋Šฅ์„ ๋”์šฑ ํ™•์žฅํ•œ ์ธํ„ฐํŽ˜์ด์Šค๋กœ, ์–‘๋ฐฉํ–ฅ ํƒ์ƒ‰๊ณผ ๋ฒ”์œ„ ๊ธฐ๋ฐ˜์˜ ์„œ๋ธŒ๋งต์„ ์ œ๊ณตํ•˜์—ฌ ๋ฐ์ดํ„ฐ๋ฅผ ๋” ํšจ์œจ์ ์œผ๋กœ ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ค€๋‹ค. TreeMap์€ NavigableMap์˜ ๋Œ€ํ‘œ์ ์ธ ๊ตฌํ˜„์ฒด๋กœ, ์ด์ง„ ํƒ์ƒ‰ ํŠธ๋ฆฌ ๊ธฐ๋ฐ˜์˜ ์„ฑ๋Šฅ๊ณผ ์ •๋ ฌ๋œ ๋งต์˜ ์žฅ์ ์„ ๋ชจ๋‘ ์ œ๊ณตํ•œ๋‹ค.