Eğitim Portalı/Java/TreeMap, LinkedHashMap ve EnumMap
Java01-java/50-treemap-ve-sirali-mapler

TreeMap, LinkedHashMap ve EnumMap

HashMap hızlıdır ama elemanları sırasız tutar. Çoğu zaman buna ihtiyacın yoktur — ama bazen anahtarların sıralı olması, ekleme sırasının korunması veya enum anahtarlar için özel hız gerekir. Bu konuda Map ailesinin üç…

TreeMap, LinkedHashMap ve EnumMap

HashMap hızlıdır ama elemanları sırasız tutar. Çoğu zaman buna ihtiyacın yoktur — ama bazen anahtarların sıralı olması, ekleme sırasının korunması veya enum anahtarlar için özel hız gerekir. Bu konuda Map ailesinin üç önemli üyesini ele alıyoruz; her biri belirli bir ihtiyaca yanıt verir.

TreeMap: sıralı anahtarlar

TreeMap, anahtarları her zaman sıralı tutar (doğal sıra veya verdiğin Comparator). İçte kırmızı-siyah ağaç kullanır; erişim O(log n)'dir (HashMap'ten yavaş ama sıralılık sağlar). Asıl gücü, sıralı yapının getirdiği komşuluk ve aralık sorgularıdır:

map.firstKey(); map.lastKey();           // uçlar
map.floorKey(80);   // <=80 en büyük anahtar
map.ceilingKey(80); // >=80 en küçük
map.higherKey(85); map.lowerKey(85);     // kesin büyük/küçük
map.headMap(85); map.tailMap(85); map.subMap(70, 90); // aralık görünümleri
map.descendingMap();                     // ters sıra

Örnek 1 (./Ornek1.java) bunların hepsini gösterir. "Şu değere en yakın", "şu aralıktakiler", "sıralı gez" gibi ihtiyaçlarda HashMap yetmez; TreeMap gerekir (örn. fiyat aralığı sorguları, zaman serisi).

LinkedHashMap: ekleme sırası ve LRU

LinkedHashMap, HashMap'in hızını korur ama ek olarak ekleme sırasını hatırlar. Üzerine gezdiğinde elemanlar eklendikleri sırada gelir — rapor/çıktı tutarlılığı için kullanışlıdır.

Daha güçlü bir kullanım: yapıcıya accessOrder=true verip removeEldestEntry'yi override ederek kolayca bir LRU (Least Recently Used) önbellek kurabilirsin:

new LinkedHashMap<>(16, 0.75f, true) {
    protected boolean removeEldestEntry(Map.Entry e) { return size() > 3; }
};

Burada her erişim elemanı "en yeni" yapar; kapasite aşılınca en az kullanılan atılır. Örnek 2 (./Ornek2.java) hem ekleme sırasını hem LRU önbelleği gösterir.

EnumMap: enum anahtarlar için

Anahtarların bir enum olduğu durumlarda EnumMap kullan. İçte basit bir dizi tutar (enum'un ordinal'ine göre); bu yüzden HashMap'ten daha hızlı ve daha kompakttır ve anahtarları enum tanım sırasında tutar:

EnumMap<Gun, String> program = new EnumMap<>(Gun.class);
program.put(Gun.PZT, "Toplantı");

Hangisini seçmeli?

İhtiyaçSınıf
Hızlı, sıra önemsizHashMap
Ekleme sırası korunsunLinkedHashMap
LRU önbellekLinkedHashMap (accessOrder)
Anahtarlar sıralı / aralık sorgusuTreeMap
Anahtar bir enumEnumMap
Çok thread'liConcurrentHashMap

Özet

Üç özel Map'i öğrendik: sıralı anahtarlar ve komşuluk/aralık sorguları için TreeMap (Örnek 1); ekleme sırasını koruyan ve kolay LRU önbellek sağlayan LinkedHashMap ile enum anahtarlar için hızlı EnumMap (Örnek 2). Doğru map'i ihtiyaca göre seçmek hem performans hem doğruluk kazandırır. Sırada, benzersizlik garantisi veren koleksiyonlar: Set aileleri (HashSet, LinkedHashSet, TreeSet, EnumSet).

Kod Örnekleri(2)

Ornek1

çalıştırılabilir
Ornek1.java
1// Ornek1: TreeMap — anahtarları SIRALI tutar, aralık ve komşuluk sorguları sağlar.
2// Çalıştırma: java Ornek1.java
3import java.util.TreeMap;
4
5public class Ornek1 {
6
7    public static void main(String[] args) {
8        TreeMap<Integer, String> notlar = new TreeMap<>();
9        notlar.put(85, "Ada"); notlar.put(60, "Can");
10        notlar.put(95, "Derya"); notlar.put(72, "Burak");
11
12        // Anahtarlar her zaman SIRALI (artan) tutulur:
13        System.out.println("Sıralı: " + notlar);
14        System.out.println("En düşük: " + notlar.firstKey() + ", En yüksek: " + notlar.lastKey());
15
16        // Komşuluk sorguları (navigation):
17        System.out.println("floorKey(80)   = " + notlar.floorKey(80));    // <=80 en büyük -> 72
18        System.out.println("ceilingKey(80) = " + notlar.ceilingKey(80));  // >=80 en küçük -> 85
19        System.out.println("higherKey(85)  = " + notlar.higherKey(85));   // >85 en küçük -> 95
20        System.out.println("lowerKey(85)   = " + notlar.lowerKey(85));    // <85 en büyük -> 72
21
22        // Aralık (range) görünümleri:
23        System.out.println("headMap(85)  (85'ten küçük): " + notlar.headMap(85));
24        System.out.println("tailMap(85)  (85 ve üstü)  : " + notlar.tailMap(85));
25        System.out.println("subMap(70,90)(70-90 arası) : " + notlar.subMap(70, 90));
26
27        // Ters sıra:
28        System.out.println("descendingMap: " + notlar.descendingMap());
29
30        System.out.println("""
31
32                --- TreeMap ---
33                Anahtarları SIRALI tutar (doğal sıra veya verilen Comparator). Erişim O(log n) (kırmızı-siyah ağaç).
34                Ekstra güç: firstKey/lastKey, floor/ceiling/higher/lowerKey (komşuluk),
35                headMap/tailMap/subMap (aralık), descendingMap (ters).
36                Ne zaman: "şu değere en yakın", "şu aralıktakiler", "sıralı gez" gerektiğinde HashMap yetmez.""");
37    }
38}
Çıktı yerel JDK 21 ile yakalandı — tarayıcıda JVM çalışmaz.

Ornek2

çalıştırılabilir
Ornek2.java
1// Ornek2: LinkedHashMap (ekleme/erişim sırası, LRU önbellek) ve EnumMap.
2// Çalıştırma: java Ornek2.java
3import java.util.EnumMap;
4import java.util.LinkedHashMap;
5import java.util.Map;
6
7public class Ornek2 {
8
9    enum Gun { PZT, SAL, CAR, PER, CUM }
10
11    public static void main(String[] args) {
12        // LinkedHashMap: EKLEME sırasını korur (HashMap'in aksine).
13        LinkedHashMap<String, Integer> sirali = new LinkedHashMap<>();
14        sirali.put("ilk", 1); sirali.put("ikinci", 2); sirali.put("üçüncü", 3);
15        System.out.println("LinkedHashMap (ekleme sırası): " + sirali);
16
17        // LRU önbellek: accessOrder=true + removeEldestEntry ile en az kullanılanı atar.
18        Map<String, String> lru = new LinkedHashMap<>(16, 0.75f, true) {
19            @Override protected boolean removeEldestEntry(Map.Entry<String, String> e) {
20                return size() > 3;   // en fazla 3 eleman tut
21            }
22        };
23        lru.put("a", "A"); lru.put("b", "B"); lru.put("c", "C");
24        lru.get("a");               // 'a'ya eriş -> en yeni kullanılan olur
25        lru.put("d", "D");          // kapasite aşıldı -> en eski (b) atılır
26        System.out.println("LRU önbellek (a erişildi, d eklendi): " + lru.keySet());
27
28        // EnumMap: anahtar bir enum ise çok hızlı ve kompakt (içte dizi kullanır).
29        EnumMap<Gun, String> program = new EnumMap<>(Gun.class);
30        program.put(Gun.PZT, "Toplantı");
31        program.put(Gun.CUM, "Demo");
32        System.out.println("EnumMap (enum sırasında): " + program);
33
34        System.out.println("""
35
36                --- LinkedHashMap ve EnumMap ---
37                LinkedHashMap: HashMap hızı + EKLEME sırasını koruma. accessOrder=true ile ERİŞİM sırası ->
38                  removeEldestEntry ile kolay LRU (Least Recently Used) önbellek.
39                EnumMap: anahtarlar bir enum ise; içte dizi kullanır -> HashMap'ten daha hızlı ve kompakt,
40                  anahtarları enum tanım sırasında tutar.
41                Özet: sırasız+hızlı -> HashMap, ekleme sırası -> LinkedHashMap, sıralı -> TreeMap, enum -> EnumMap.""");
42    }
43}
Çıktı yerel JDK 21 ile yakalandı — tarayıcıda JVM çalışmaz.