Ders İçeriği

Java Koleksiyonlar Çerçevesi (Java Collections Framework - JCF), Java programlama dilinde veri gruplarını depolamak ve işlemek için kullanılan bir dizi sınıf ve arayüzden oluşur. Bu çerçeve, veri yapılarını (listeler, kümeler, haritalar vb.) standartlaştırarak geliştiricilere güçlü ve esnek araçlar sunar. JCF, kodun yeniden kullanılabilirliğini artırır, geliştirme süresini kısaltır ve performans açısından optimize edilmiş algoritmalar sağlar.

Koleksiyonlar Çerçevesi'nin Temel Arayüzleri

JCF, hiyerarşik bir yapıya sahiptir ve temel olarak üç ana arayüz etrafında döner:

  1. Collection Arayüzü: Bir grup nesneyi temsil eden en temel arayüzdür. ListSet ve Queue arayüzleri bu arayüzden türemiştir.
  2. List Arayüzü: Elemanların sıralı bir şekilde depolandığı ve indeks numaralarıyla erişilebildiği koleksiyonları tanımlar. Tekrar eden elemanlara izin verir.
    • Uygulayan Sınıflar: ArrayListLinkedListVector.
  3. Set Arayüzü: Tekrar eden elemanlara izin vermeyen koleksiyonları tanımlar. Elemanların belirli bir sırası garanti edilmez (bazı uygulamalar hariç).
    • Uygulayan Sınıflar: HashSetLinkedHashSetTreeSet.
  4. Queue Arayüzü: Elemanların belirli bir sıraya göre (genellikle FIFO - İlk Giren İlk Çıkar) işlendiği koleksiyonları tanımlar.
    • Uygulayan Sınıflar: PriorityQueueArrayDeque.
  5. Map Arayüzü: Anahtar-değer çiftlerini depolayan koleksiyonları tanımlar. Her anahtar benzersiz olmalıdır, ancak değerler tekrar edebilir. Map arayüzü, Collection arayüzünden türememiştir, ancak JCF'nin önemli bir parçasıdır.
    • Uygulayan Sınıflar: HashMapLinkedHashMapTreeMapHashtable.

Yaygın Kullanılan Koleksiyon Sınıfları

List Uygulamaları

  • ArrayList: Dinamik boyutlu bir dizidir. Elemanlara indeks numarasıyla hızlı erişim sağlar. Eleman ekleme ve silme işlemleri, listenin sonuna doğru yapıldığında hızlıdır, ancak ortasına yapıldığında maliyetli olabilir.

import java.util.ArrayList;
import java.util.List;

public class ArrayListOrnek {
    public static void main(String[] args) {
        List<String> isimler = new ArrayList<>();
        isimler.add("Ahmet");
        isimler.add("Ayşe");
        isimler.add("Mehmet");
        isimler.add(1, "Zeynep"); // 1. indekse Zeynep ekle

        System.out.println(isimler); // [Ahmet, Zeynep, Ayşe, Mehmet]
        System.out.println(isimler.get(0)); // Ahmet
        isimler.remove("Ayşe");
        System.out.println(isimler); // [Ahmet, Zeynep, Mehmet]
    }
}

LinkedList: Çift yönlü bağlı liste yapısını kullanır. Eleman ekleme ve silme işlemleri hızlıdır, ancak indeks numarasıyla erişim (rastgele erişim) yavaştır.

import java.util.LinkedList;
import java.util.List;

public class LinkedListOrnek {
    public static void main(String[] args) {
        List<String> sehirler = new LinkedList<>();
        sehirler.add("Ankara");
        sehirler.add("İstanbul");
        sehirler.addFirst("İzmir"); // Başa ekle

        System.out.println(sehirler); // [İzmir, Ankara, İstanbul]
        System.out.println(sehirler.getLast()); // İstanbul
    }
}

Set Uygulamaları

  • HashSet: Elemanları hash tablosu kullanarak depolar. Elemanların sırası garanti edilmez ve null eleman içerebilir. En hızlı Set uygulamasıdır.

import java.util.HashSet;
import java.util.Set;

public class HashSetOrnek {
    public static void main(String[] args) {
        Set<String> renkler = new HashSet<>();
        renkler.add("Kırmızı");
        renkler.add("Mavi");
        renkler.add("Yeşil");
        renkler.add("Kırmızı"); // Tekrar eden eleman eklenmez

        System.out.println(renkler); // [Yeşil, Kırmızı, Mavi] (Sıra değişebilir)
        System.out.println(renkler.contains("Mavi")); // true
    }
}

TreeSet: Elemanları doğal sıralamalarına göre veya bir Comparator kullanarak sıralı bir şekilde depolar. Performansı HashSet'ten daha düşüktür, ancak sıralı erişim sağlar.

import java.util.TreeSet;
import java.util.Set;

public class TreeSetOrnek {
    public static void main(String[] args) {
        Set<Integer> sayilar = new TreeSet<>();
        sayilar.add(5);
        sayilar.add(2);
        sayilar.add(8);
        sayilar.add(2); // Tekrar eden eleman eklenmez

        System.out.println(sayilar); // [2, 5, 8] (Sıralı)
    }
}

Map Uygulamaları

  • HashMap: Anahtar-değer çiftlerini hash tablosu kullanarak depolar. Anahtarlar benzersiz olmalıdır. Elemanların sırası garanti edilmez. En hızlı Map uygulamasıdır.

import java.util.HashMap;
import java.util.Map;

public class HashMapOrnek {
    public static void main(String[] args) {
        Map<String, String> baskentler = new HashMap<>();
        baskentler.put("Türkiye", "Ankara");
        baskentler.put("Fransa", "Paris");
        baskentler.put("Almanya", "Berlin");
        baskentler.put("Türkiye", "İstanbul"); // Anahtar tekrar ettiği için değeri günceller

        System.out.println(baskentler); // {Fransa=Paris, Türkiye=İstanbul, Almanya=Berlin}
        System.out.println(baskentler.get("Fransa")); // Paris
        System.out.println(baskentler.containsKey("İtalya")); // false
        System.out.println(baskentler.keySet()); // [Fransa, Türkiye, Almanya]
        System.out.println(baskentler.values()); // [Paris, İstanbul, Berlin]
    }
}

TreeMap: Anahtar-değer çiftlerini anahtarların doğal sıralamasına göre veya bir Comparator kullanarak sıralı bir şekilde depolar. Performansı HashMap'ten daha düşüktür, ancak sıralı erişim sağlar.

import java.util.TreeMap;
import java.util.Map;

public class TreeMapOrnek {
    public static void main(String[] args) {
        Map<String, Integer> ogrenciNotlari = new TreeMap<>();
        ogrenciNotlari.put("Ayşe", 85);
        ogrenciNotlari.put("Ahmet", 90);
        ogrenciNotlari.put("Zeynep", 78);

        System.out.println(ogrenciNotlari); // {Ahmet=90, Ayşe=85, Zeynep=78} (Anahtarlar sıralı)
    }
}

Koleksiyonlar Üzerinde Gezinme (Iterating)

Koleksiyonlardaki elemanlar üzerinde gezinmek için çeşitli yöntemler bulunur:

  • Geliştirilmiş For Döngüsü (Enhanced For Loop): En basit ve yaygın yöntemdir.

List<String> meyveler = new ArrayList<>();
meyveler.add("Elma");
meyveler.add("Armut");
for (String meyve : meyveler) {
    System.out.println(meyve);
}

Iterator Arayüzü: Koleksiyonlar üzerinde güvenli bir şekilde gezinmek ve elemanları silmek için kullanılır.

import java.util.Iterator;

List<String> sebzeler = new ArrayList<>();
sebzeler.add("Domates");
sebzeler.add("Salatalık");
Iterator<String> iterator = sebzeler.iterator();
while (iterator.hasNext()) {
    String sebze = iterator.next();
    System.out.println(sebze);
    if (sebze.equals("Domates")) {
        iterator.remove(); // Güvenli silme
    }
}
System.out.println(sebzeler); // [Salatalık]

Java Koleksiyonlar Çerçevesi, veri yönetimi ve manipülasyonu için güçlü ve esnek bir temel sağlar. Doğru koleksiyon sınıfını seçmek, uygulamanızın performansını ve verimliliğini önemli ölçüde etkileyebilir. Bir sonraki derste İstisna Yönetimi konusunu inceleyeceğiz.