Array vs ArrayList Karşılaştırma
Giriş
Artık hem dizileri (array) hem de ArrayList'i biliyorsun. İkisi de "birden fazla elemanı bir arada tutmak" için kullanılıyor. Peki hangisini ne zaman kullanacaksın? Bu ders tam olarak bu soruyu yanıtlıyor.
Kısa cevap: çoğu durumda ArrayList kullan. Ama bazı senaryolarda array daha mantıklı. Neden ve ne zaman — bunu detaylıca göreceğiz.
Temel Farklar
1. Boyut
En büyük fark bu. Array sabit boyutlu, ArrayList dinamik.
// Array — boyut sabit
int[] dizi = new int[5];
// 6. eleman? Yeni dizi oluştur, kopyala... uğraş.
// ArrayList — boyut dinamik
ArrayList<Integer> liste = new ArrayList<>();
liste.add(1);
liste.add(2);
// 100 eleman daha ekle, sorun yok.Eleman sayısını önceden biliyorsan ve değişmeyecekse → Array. Eleman sayısı değişecekse → ArrayList.
2. Tip Desteği
// Array — primitive tipler desteklenir
int[] intDizi = new int[10]; // doğrudan int
double[] doubleDizi = new double[5]; // doğrudan double
// ArrayList — sadece referans tipleri
ArrayList<Integer> intListe = new ArrayList<>(); // Integer (wrapper)
ArrayList<Double> doubleListe = new ArrayList<>(); // Double (wrapper)Primitive tip dizileri bellekte çok daha verimlidir. int 4 byte yer kaplar. Integer ise en az 16 byte (nesne overhead'i yüzünden). 1 milyon elemanlı bir dizi düşün — fark devasa.
3. Sözdizimi (Syntax)
// Array
int[] dizi = new int[3];
dizi[0] = 10;
int deger = dizi[0];
int boyut = dizi.length;
// ArrayList
ArrayList<Integer> liste = new ArrayList<>();
liste.add(10); // eleman ekleme (sona)
int deger = liste.get(0); // eleman okuma
liste.set(0, 20); // eleman güncelleme
int boyut = liste.size(); // boyutArray sözdizimi daha kısa ve doğrudan. ArrayList'te her şey metot çağrısı.
4. Çok Boyutluluk
// Array — 2D, 3D kolayca
int[][] matris = new int[3][3];
matris[0][1] = 42;
// ArrayList — iç içe liste (daha karmaşık)
ArrayList<ArrayList<Integer>> matris2 = new ArrayList<>();
matris2.add(new ArrayList<>());
matris2.get(0).add(42);2D yapılar için array çok daha doğal ve okunabilir.
Performans Karşılaştırması
Bunu bir spor araba vs SUV analojisi ile düşün. Array spor araba gibi — hızlı ama esnek değil. ArrayList SUV gibi — biraz daha yavaş ama her şeyi taşır.
Elemana Erişim (get)
| İşlem | Array | ArrayList |
|---|---|---|
dizi[i] vs liste.get(i) | O(1) | O(1) |
İkisi de aynı hızda. ArrayList arka planda da array kullandığı için erişim süresi aynı.
Eleman Ekleme
| İşlem | Array | ArrayList |
|---|---|---|
| Sona ekleme | Yok (sabit boyut) | O(1) amortized |
| Araya ekleme | Manuel (O(n)) | O(n) |
ArrayList sona ekleme konusunda çok hızlı. Ama araya ekleme her ikisinde de yavaş çünkü elemanları kaydırmak gerekiyor.
Eleman Silme
| İşlem | Array | ArrayList |
|---|---|---|
| Sondan silme | Yok | O(1) |
| Aradan silme | Manuel (O(n)) | O(n) |
Bellek Kullanımı
// 1000 int — Array
int[] dizi = new int[1000];
// Yaklaşık 4000 byte (4 byte × 1000)
// 1000 Integer — ArrayList
ArrayList<Integer> liste = new ArrayList<>();
// Yaklaşık 20000+ byte (Integer nesneleri + referanslar + overhead)Array yaklaşık 5 kat daha az bellek kullanır (primitive tipler için). Bu fark büyük veri setlerinde önemli olur.
💡 İpucu: Performans farkı küçük listelerde (birkaç yüz eleman) ihmal edilebilir. "Premature optimization is the root of all evil" — önce doğru çalışan kod yaz, sonra gerekirse optimize et.
ArrayList Arka Planda Nasıl Çalışır?
ArrayList aslında içinde bir Object[] dizisi tutar. Eleman eklediğinde:
Dizide yer varsa → elemanı koy
Dizi doluysa → 1.5 kat büyük yeni dizi oluştur → elemanları kopyala → yeni elemanı koy
ArrayList<Integer> liste = new ArrayList<>(); // iç dizi boyutu: 10 (varsayılan)
// 10 eleman ekle → iç dizi doldu
// 11. eleman → yeni dizi boyutu: 15 (10 * 1.5)
// 15 eleman ekle → iç dizi doldu
// 16. eleman → yeni dizi boyutu: 22 (15 * 1.5)Bu büyüme işlemi (resize) maliyetli çünkü tüm elemanlar kopyalanıyor. Ama nadir olduğu için ortalamada (amortized) O(1).
Initial Capacity Belirtme
Eğer yaklaşık kaç eleman ekleyeceğini biliyorsan, baştan kapasite belirtebilirsin:
// 10000 eleman ekleyeceğini biliyorsan
ArrayList<Integer> liste = new ArrayList<>(10000);Bu gereksiz resize işlemlerini önler.
Dönüşümler
Array → ArrayList
String[] dizi = {"Elma", "Armut", "Portakal"};
// Yol 1: Arrays.asList
ArrayList<String> liste = new ArrayList<>(Arrays.asList(dizi));
// Yol 2: Manuel
ArrayList<String> liste2 = new ArrayList<>();
for (String s : dizi) {
liste2.add(s);
}⚠️ Dikkat: Arrays.asList() tek başına sabit boyutlu bir liste döner. add() veya remove() çağırırsan UnsupportedOperationException alırsın. Bu yüzden new ArrayList<>(Arrays.asList(...)) ile sarmalıyoruz.
// Bu listeye eleman ekleyemezsin!
List<String> sabitListe = Arrays.asList("a", "b", "c");
sabitListe.add("d"); // UnsupportedOperationException!
// Buna ekleyebilirsin
ArrayList<String> dinamikListe = new ArrayList<>(Arrays.asList("a", "b", "c"));
dinamikListe.add("d"); // sorun yokPrimitive Array → ArrayList
Primitive dizileri direkt dönüştüremezsin:
int[] intDizi = {1, 2, 3, 4, 5};
// Bu ÇALIŞMAZ
// ArrayList<Integer> liste = new ArrayList<>(Arrays.asList(intDizi));
// Manuel dönüşüm gerekli
ArrayList<Integer> liste = new ArrayList<>();
for (int sayi : intDizi) {
liste.add(sayi); // auto-boxing ile int → Integer
}ArrayList → Array
ArrayList<String> liste = new ArrayList<>(Arrays.asList("Elma", "Armut", "Portakal"));
// String dizisine dönüştür
String[] dizi = liste.toArray(new String[0]);
// veya
String[] dizi2 = liste.toArray(new String[liste.size()]);toArray(new String[0]) kullanımı Java'nın önerdiği modern yaklaşım. JVM bunu optimize eder.
ArrayList → Primitive Array
ArrayList<Integer> liste = new ArrayList<>(Arrays.asList(1, 2, 3, 4, 5));
// Manuel dönüşüm
int[] dizi = new int[liste.size()];
for (int i = 0; i < liste.size(); i++) {
dizi[i] = liste.get(i); // auto-unboxing
}Ne Zaman Array Kullan?
Eleman sayısı sabit ve biliniyor — haftanın 7 günü, yılın 12 ayı
Performans kritik — milyon elemanlı veri, oyun döngüsü
Primitive tipler —
int[],double[]gibi (bellek tasarrufu)Çok boyutlu yapılar — matrisler, grid'ler, oyun tahtaları
Düşük seviye işlemler — byte dizileri, dosya okuma/yazma
// İyi array kullanımı
byte[] dosyaIcerigi = Files.readAllBytes(path); // dosya okuma
int[][] sudoku = new int[9][9]; // oyun tahtası
double[] sinyal = new double[44100]; // ses verisi (1 saniyelik)Ne Zaman ArrayList Kullan?
Eleman sayısı değişecek — kullanıcı listesi, sepet, log kaydı
Sık ekleme/silme — dinamik koleksiyon
Hazır metotlara ihtiyaç var —
contains,indexOf,removeGenel amaçlı kullanım — çoğu iş mantığı
// İyi ArrayList kullanımı
ArrayList<String> sepet = new ArrayList<>(); // alışveriş sepeti
ArrayList<String> loglar = new ArrayList<>(); // log kayıtları
ArrayList<Integer> rastgeleSayilar = new ArrayList<>(); // bilinmeyen sayıdaPratik Karar Rehberi
Kendine şu soruları sor:
1. Eleman sayısı değişecek mi?
Evet → ArrayList
Hayır → Array veya ArrayList (ikisi de olur)
2. Primitive tip mi?
Evet + performans önemli → Array
Evet + performans önemsiz → ArrayList (wrapper ile)
Hayır → ArrayList
3. Çok boyutlu mu?
Evet → Array (çok daha kolay)
Hayır → ArrayList
4. Emin değil misin?
→ ArrayList (daha güvenli tercih)💡 İpucu: Emin değilsen ArrayList kullan. Daha sonra performans sorunu çıkarsa Array'e geçmek kolaydır. Ama Array'den ArrayList'e geçmek daha zahmetli (tüm sözdizimini değiştirmen gerekir).
Pratik Örnek: İkisini Birlikte Kullanma
import java.util.ArrayList;
import java.util.Arrays;
public class NotSistemi {
public static void main(String[] args) {
// Dersler sabit → array
String[] dersler = {"Matematik", "Fizik", "Kimya"};
// Öğrenciler dinamik → ArrayList
ArrayList<String> ogrenciler = new ArrayList<>();
ogrenciler.add("Ali");
ogrenciler.add("Ayse");
// Notlar sabit boyut (3 ders) → array
int[] aliNotlari = {85, 90, 78};
int[] ayseNotlari = {92, 88, 95};
// Her öğrenci için rapor
System.out.println(ogrenciler.get(0) + ": " + Arrays.toString(aliNotlari));
System.out.println(ogrenciler.get(1) + ": " + Arrays.toString(ayseNotlari));
// Yeni öğrenci geldi (ArrayList olduğu için sorun yok)
ogrenciler.add("Mehmet");
System.out.println("Toplam öğrenci: " + ogrenciler.size());
}
}Bu örnekte dersler sabit olduğu için array, öğrenciler dinamik olduğu için ArrayList kullandık. Gerçek projelerde de böyle karma kullanım sık görülür.
List Arayüzü (Interface) — Bonus
İleride OOP konularına geldiğinde List arayüzünü göreceksin. Şimdilik şunu bil:
// ArrayList yerine List tipinde tanımlama (tercih edilen)
List<String> isimler = new ArrayList<>();Bu şekilde tanımlama, ileride ArrayList yerine LinkedList kullanmak istediğinde sadece sağ tarafı değiştirmeni sağlar. "Program to an interface, not an implementation" prensibi. Şimdilik sadece gör, ileride detaylı işleyeceğiz.
Özet
Array: sabit boyut, primitive destekler, daha hızlı, daha az bellek, sözdizimi basit
ArrayList: dinamik boyut, sadece referans tipler, hazır metotlar (
add,remove,contains), daha esnekÇoğu durumda ArrayList tercih edilir — esneklik ve kolaylık kazandırır
Performans kritik ve eleman sayısı sabit ise Array tercih edilir
Dönüşümler:
Arrays.asList()+new ArrayList<>()(array→list),toArray()(list→array)Şüphede kalırsan ArrayList seç, gerekirse sonra optimize et
AI Asistan
Sorularını yanıtlamaya hazır