Eğitim Portalı/Java/HashMap Sınıfı
Java01-java/49-hashmap

HashMap Sınıfı

HashMap, bir anahtarı bir değere eşleyen koleksiyondur (key → value) ve ArrayList'ten sonra en çok kullanılan veri yapısıdır. "Kullanıcı adından kullanıcıya", "ürün kodundan stoğa", "kelimeden sayısına"... gibi her tü…

HashMap Sınıfı

HashMap, bir anahtarı bir değere eşleyen koleksiyondur (key → value) ve ArrayList'ten sonra en çok kullanılan veri yapısıdır. "Kullanıcı adından kullanıcıya", "ürün kodundan stoğa", "kelimeden sayısına"... gibi her türlü eşleme için kullanılır. En güçlü yanı hızıdır: doğru kurulmuş bir HashMap'te anahtarla erişim ortalama O(1)'dir.

Nasıl çalışır? (hash mantığı)

HashMap, anahtarın hashCode() değerini kullanarak değeri bir "kovaya" (bucket) yerleştirir. Aradığında aynı hash'i hesaplayıp doğrudan o kovaya gider — bu yüzden çok hızlıdır. Bu mekanizmanın düzgün çalışması için anahtar nesnelerin equals() ve hashCode() metotları doğru tanımlanmalıdır. String, Integer gibi tipler bunu zaten doğru yapar; kendi sınıfını anahtar yapacaksan ikisini birlikte override et (record'lar bunu otomatik sağlar).

Temel işlemler

Map<String,Integer> m = new HashMap<>();
m.put("a", 1);                 // ekle/güncelle (aynı anahtar değeri değiştirir)
m.get("a");                    // eriş (yoksa null)
m.getOrDefault("x", 0);        // yoksa varsayılan döndür (null'dan kurtulur)
m.containsKey("a");            // anahtar var mı?
m.containsValue(1);            // değer var mı?
m.remove("a");                 // sil
m.size();                      // kayıt sayısı

Gezinme — en verimlisi entrySet() (anahtar+değer birlikte):

for (Map.Entry<String,Integer> e : m.entrySet()) { e.getKey(); e.getValue(); }
m.keySet();  m.values();  m.forEach((k,v) -> ...);

Örnek 1 (./Ornek1.java) bunların hepsini bir stok haritasıyla gösterir.

Sıra garantisi yoktur: HashMap elemanları hash sırasına göre tutar (öngörülemez). Ekleme sırası gerekiyorsa LinkedHashMap, sıralı anahtar gerekiyorsa TreeMap kullan (sonraki konu). HashMap bir null anahtara ve birden çok null değere izin verir.

Güçlü metotlar (Java 8+)

HashMap'in asıl gücü bu metotlardadır; çok yazılan kalıpları tek satıra indirir:

m.merge(k, 1, Integer::sum);                       // sayaç: yoksa 1, varsa topla
m.computeIfAbsent(k, x -> new ArrayList<>()).add(v); // gruplama: Map<K,List<V>>
m.compute(k, (key, val) -> ...);                   // değeri yeniden hesapla
m.putIfAbsent(k, v);                               // yalnızca yoksa koy

Örnek 2 (./Ornek2.java) iki klasik gerçek senaryoyu çözer: kelime frekansı (merge) ve gruplama (computeIfAbsent ile Map<Integer, List<String>>). Bu kalıpları çok kullanacaksın.

HashMap aile fertleri

SınıfÖzellikNe zaman
HashMapHızlı, sırasızVarsayılan eşleme
LinkedHashMapEkleme/erişim sırasını korurSıra önemliyse, LRU önbellek
TreeMapAnahtarları sıralı tutarSıralı/aralık sorguları
EnumMapEnum anahtarlar için çok hızlıAnahtar bir enum'sa
ConcurrentHashMapThread-safeÇok thread'li erişim

Sıralı ve özel map'leri (TreeMap, LinkedHashMap, EnumMap) bir sonraki konuda ele alıyoruz.

Özet

HashMap'in anahtar-değer eşlemesini, hash tabanlı O(1) erişimini ve equals/hashCode gereksinimini; temel işlemleri ve gezinmeyi (Örnek 1); merge/computeIfAbsent gibi güçlü metotlarla frekans sayma ve gruplama gerçek senaryolarını (Örnek 2) öğrendik. Sırada, anahtarları sıralı veya belirli bir düzende tutan map'ler: TreeMap, LinkedHashMap ve EnumMap.

Kod Örnekleri(2)

Ornek1

çalıştırılabilir
Ornek1.java
1// Ornek1: HashMap — anahtar-değer temel işlemleri ve gezinme.
2// Çalıştırma: java Ornek1.java
3import java.util.HashMap;
4import java.util.Map;
5
6public class Ornek1 {
7
8    public static void main(String[] args) {
9        Map<String, Integer> stok = new HashMap<>();
10
11        // Ekleme/güncelleme (aynı anahtar -> değer güncellenir)
12        stok.put("klavye", 10);
13        stok.put("mouse", 25);
14        stok.put("monitör", 5);
15        stok.put("klavye", 12);   // var olan anahtarı GÜNCELLER
16        System.out.println("Stok: " + stok);
17
18        // Erişim
19        System.out.println("mouse: " + stok.get("mouse"));
20        System.out.println("kulaklık: " + stok.get("kulaklık"));              // yoksa null
21        System.out.println("kulaklık (varsayılan): " + stok.getOrDefault("kulaklık", 0)); // null yerine 0
22
23        // Var mı? / sil
24        System.out.println("klavye var mı? " + stok.containsKey("klavye"));
25        System.out.println("5 değeri var mı? " + stok.containsValue(5));
26        stok.remove("monitör");
27        System.out.println("Silme sonrası: " + stok);
28
29        // Gezinme: entrySet (anahtar+değer birlikte — en verimli)
30        System.out.println("\nTüm kayıtlar:");
31        for (Map.Entry<String, Integer> e : stok.entrySet()) {
32            System.out.println("  " + e.getKey() + " -> " + e.getValue());
33        }
34        // keySet / values ayrı ayrı da gezilebilir; forEach de var:
35        stok.forEach((k, v) -> System.out.println("  forEach: " + k + "=" + v));
36
37        System.out.println("""
38
39                --- HashMap temelleri ---
40                Anahtar -> değer eşlemesi; anahtarlar BENZERSİZdir (aynı anahtar değeri günceller).
41                put/get/getOrDefault/containsKey/remove en sık metotlardır; erişim ortalama O(1).
42                SIRA GARANTİSİ YOKTUR (hash sırası). Ekleme sırası için LinkedHashMap, sıralı için TreeMap.
43                Gezinme: entrySet() (anahtar+değer), keySet(), values(), forEach.""");
44    }
45}
Çıktı yerel JDK 21 ile yakalandı — tarayıcıda JVM çalışmaz.

Ornek2

çalıştırılabilir
Ornek2.java
1// Ornek2: HashMap güçlü metotları — merge, compute, computeIfAbsent, putIfAbsent.
2// Gerçek senaryo: kelime frekansı ve gruplama.
3// Çalıştırma: java Ornek2.java
4import java.util.ArrayList;
5import java.util.HashMap;
6import java.util.List;
7import java.util.Map;
8
9public class Ornek2 {
10
11    public static void main(String[] args) {
12        String metin = "elma armut elma kiraz armut elma muz kiraz elma";
13
14        // 1) Kelime frekansı — merge: anahtar yoksa 1 koy, varsa eskiyle topla.
15        Map<String, Integer> frekans = new HashMap<>();
16        for (String kelime : metin.split(" ")) {
17            frekans.merge(kelime, 1, Integer::sum);
18        }
19        System.out.println("Frekanslar: " + frekans);
20
21        // getOrDefault ile aynı iş (alternatif):
22        Map<String, Integer> frekans2 = new HashMap<>();
23        for (String k : metin.split(" ")) {
24            frekans2.put(k, frekans2.getOrDefault(k, 0) + 1);
25        }
26        System.out.println("getOrDefault ile: " + frekans2);
27
28        // 2) Gruplama — computeIfAbsent: anahtar yoksa boş liste oluştur, sonra ekle.
29        Map<Integer, List<String>> uzunlugaGore = new HashMap<>();
30        for (String k : new String[]{"at", "kuş", "fil", "kedi", "kuğu"}) {
31            uzunlugaGore.computeIfAbsent(k.length(), uzunluk -> new ArrayList<>()).add(k);
32        }
33        System.out.println("Uzunluğa göre grup: " + uzunlugaGore);
34
35        // 3) putIfAbsent / compute
36        frekans.putIfAbsent("elma", 999);  // 'elma' zaten var -> DEĞİŞMEZ
37        frekans.compute("muz", (k, v) -> v == null ? 1 : v * 10); // 'muz' -> 1*10
38        System.out.println("putIfAbsent/compute sonrası: elma=" + frekans.get("elma") + ", muz=" + frekans.get("muz"));
39
40        System.out.println("""
41
42                --- HashMap güçlü metotları ---
43                merge(k, val, fn)        : yoksa val koy, varsa fn(eski,val) ile birleştir. (sayaç için ideal)
44                computeIfAbsent(k, fn)   : yoksa fn ile üret-koy. (Map<K, List<V>> gruplama için ideal)
45                compute(k, fn)/computeIfPresent: değeri (eski+anahtar)'a göre yeniden hesapla.
46                putIfAbsent(k, val)      : yalnızca anahtar yoksa koy.
47                ÖNEMLİ: anahtar nesnelerin equals() ve hashCode()'u doğru tanımlanmalı (aksi halde bulunamaz).""");
48    }
49}
Çıktı yerel JDK 21 ile yakalandı — tarayıcıda JVM çalışmaz.