Tek Boyutlu Diziler
Giriş
Şimdiye kadar değişkenlerle çalıştık. Bir tane int sayi = 5; dedik, bir tane değer tuttuk. Peki ya 100 öğrencinin notunu saklamak istersen? 100 tane değişken mi tanımlayacaksın? not1, not2, not3... Hayır, tabii ki hayır.
İşte tam burada diziler (arrays) devreye giriyor. Dizi, aynı türden birden fazla değeri tek bir isim altında saklayan veri yapısıdır. Bir dizi tanımladığında, bellekte yan yana kutucuklar açılır ve her kutucuğa bir numara (indeks) verilir.
Dizi Nedir?
Diziyi bir apartman gibi düşün. Apartmanın adı var (dizinin adı), her dairenin numarası var (indeks), ve her dairede bir kişi oturuyor (değer). 3 numaralı daireye gitmek istiyorsan, apartmanın adını ve daire numarasını bilmen yeterli.
Java'da diziler:
Sabit boyutludur — oluşturduktan sonra büyütemez veya küçültemezsin
Aynı türden elemanlar tutar —
intdizisi sadeceinttutarSıfırdan indekslenir — ilk eleman 0. indekste, ikinci eleman 1. indekste
Bu üç özellik dizilerin en temel kurallarıdır. Şimdi nasıl tanımlanır, bakalım.
Dizi Tanımlama
Java'da dizi tanımlamanın birkaç yolu var. Hepsini görelim.
Yol 1: Önce Tanımla, Sonra Oluştur
int[] notlar; // dizi değişkeni tanımlandı (henüz bellekte yer yok)
notlar = new int[5]; // 5 elemanlık yer açıldı bellekteBurada new int[5] dediğinde, bellekte 5 tane int kutucuk açılıyor. Hepsi varsayılan değerle (0) doluyor.
Yol 2: Tek Satırda Tanımla ve Oluştur
int[] notlar = new int[5]; // en yaygın kullanım
String[] isimler = new String[10];
double[] fiyatlar = new double[100];Yol 3: Değerlerle Birlikte Oluştur
int[] notlar = {90, 85, 72, 95, 60};
String[] gunler = {"Pazartesi", "Sali", "Carsamba"};Bu yöntemde boyutu sen belirtmiyorsun — Java eleman sayısına bakarak kendisi hesaplıyor.
Yol 4: new ile Değer Vererek
int[] notlar = new int[]{90, 85, 72, 95, 60};Bu yöntem özellikle metoda parametre olarak dizi geçerken işe yarar.
💡 İpucu: Günlük kullanımda Yol 2 (boş dizi) ve Yol 3 (değerli dizi) en çok karşına çıkacak olanlar. Diğerlerini bilmen yeterli, ezberlemene gerek yok.
Varsayılan Değerler
new ile dizi oluşturduğunda, Java tüm elemanları varsayılan değerlerle doldurur:
| Tür | Varsayılan Değer |
|---|---|
int, short, byte, long | 0 |
float, double | 0.0 |
boolean | false |
char | '\u0000' (boş karakter) |
Referans tipleri (String, vs.) | null |
int[] sayilar = new int[3];
System.out.println(sayilar[0]); // 0
System.out.println(sayilar[1]); // 0
System.out.println(sayilar[2]); // 0
String[] isimler = new String[2];
System.out.println(isimler[0]); // nullBu varsayılan değerler önemli. Özellikle String dizilerinde null kontrolü yapmayı unutma, yoksa NullPointerException alırsın.
Elemanlara Erişim ve Değer Atama
Dizinin elemanlarına indeks ile erişirsin. İndeksler 0'dan başlar.
int[] notlar = new int[5];
// Değer atama
notlar[0] = 90;
notlar[1] = 85;
notlar[2] = 72;
notlar[3] = 95;
notlar[4] = 60;
// Değer okuma
System.out.println("İlk not: " + notlar[0]); // 90
System.out.println("Son not: " + notlar[4]); // 60
// Değer güncelleme
notlar[2] = 78; // 72 yerine 78 oldu5 elemanlı bir dizide geçerli indeksler: 0, 1, 2, 3, 4. Yani son indeks = boyut - 1.
length Özelliği
Her dizinin bir length özelliği vardır. Dizideki eleman sayısını verir.
int[] notlar = {90, 85, 72, 95, 60};
System.out.println("Eleman sayısı: " + notlar.length); // 5
// Son elemana erişim
System.out.println("Son not: " + notlar[notlar.length - 1]); // 60⚠️ Dikkat: length bir metot değil, bir field'dır. Parantez kullanmıyorsun: notlar.length ✅ — notlar.length() ❌. String'te length() metot, dizide length field. Bu farkı unutma.
Dizi Üzerinde Gezinme
Dizinin tüm elemanlarını işlemek istediğinde döngü kullanırsın. İki temel yol var.
for Döngüsü ile Gezinme
int[] notlar = {90, 85, 72, 95, 60};
for (int i = 0; i < notlar.length; i++) {
System.out.println("Not " + i + ": " + notlar[i]);
}Bu klasik yöntem. İndeks numarasına ihtiyacın varsa (mesela "3. öğrenci" demek istiyorsan) bunu kullan.
for-each (Enhanced for) ile Gezinme
int[] notlar = {90, 85, 72, 95, 60};
for (int not : notlar) {
System.out.println("Not: " + not);
}for (int not : notlar) şunu diyor: "notlar dizisindeki her elemanı sırayla not değişkenine ata ve döngü gövdesini çalıştır."
for-each daha temiz ve okunabilir. Ama dezavantajı var: indeks numarasını bilmiyorsun ve elemanı değiştiremiyorsun.
int[] notlar = {90, 85, 72};
// Bu ÇALIŞMAZ — orijinal dizi değişmez
for (int not : notlar) {
not = not + 10; // sadece lokal kopya değişir
}
System.out.println(notlar[0]); // hâlâ 90
// Bunu yapman lazım
for (int i = 0; i < notlar.length; i++) {
notlar[i] = notlar[i] + 10; // orijinal dizi değişir
}
System.out.println(notlar[0]); // 100💡 İpucu: Sadece okuma yapıyorsan → for-each. Elemanları değiştirmek veya indeks lazımsa → klasik for.
while ile Gezinme
Klasik for yerine while da kullanabilirsin, ama dizilerde pek tercih edilmez:
int[] sayilar = {10, 20, 30, 40};
int i = 0;
while (i < sayilar.length) {
System.out.println(sayilar[i]);
i++;
}Sonuç aynı, ama for döngüsü bu iş için daha doğal ve okunabilir.
ArrayIndexOutOfBoundsException
Java'da dizilerle çalışırken en sık karşılaşacağın hata bu. Var olmayan bir indekse erişmeye çalıştığında Java sana bu hatayı fırlatır.
int[] notlar = {90, 85, 72}; // indeksler: 0, 1, 2
System.out.println(notlar[3]); // HATA! 3. indeks yok
System.out.println(notlar[-1]); // HATA! Negatif indeks yokÇıktı:
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: Index 3 out of bounds for length 3Bu hatanın en yaygın senaryoları:
int[] dizi = new int[5];
// Senaryo 1: <= yerine < kullanmayı unutmak
for (int i = 0; i <= dizi.length; i++) { // HATA! i=5 olduğunda patlıyor
System.out.println(dizi[i]);
}
// Doğrusu
for (int i = 0; i < dizi.length; i++) { // i en fazla 4 olur
System.out.println(dizi[i]);
}
// Senaryo 2: Boş dizi kontrolü yapmamak
int[] bos = new int[0]; // boş dizi (geçerli!)
System.out.println(bos[0]); // HATA! Eleman yok⚠️ Dikkat: Döngülerde i <= dizi.length yazmak en klasik hatadır. Her zaman i < dizi.length kullan. Eşittir işareti seni yakacak.
Pratik Örnekler
Örnek 1: Dizinin Toplamı ve Ortalaması
int[] notlar = {90, 85, 72, 95, 60};
int toplam = 0;
for (int not : notlar) {
toplam += not;
}
double ortalama = (double) toplam / notlar.length;
System.out.println("Toplam: " + toplam); // 402
System.out.println("Ortalama: " + ortalama); // 80.4Burada (double) cast'ına dikkat et. Yoksa int / int sonucu yine int olur ve virgüllü kısım kaybolur.
Örnek 2: En Büyük ve En Küçük Eleman
int[] sayilar = {34, 12, 89, 5, 67, 43};
int enBuyuk = sayilar[0];
int enKucuk = sayilar[0];
for (int i = 1; i < sayilar.length; i++) {
if (sayilar[i] > enBuyuk) {
enBuyuk = sayilar[i];
}
if (sayilar[i] < enKucuk) {
enKucuk = sayilar[i];
}
}
System.out.println("En büyük: " + enBuyuk); // 89
System.out.println("En küçük: " + enKucuk); // 5İlk elemanı başlangıç değeri olarak alıyoruz ve geri kalanlarla karşılaştırıyoruz. Integer.MIN_VALUE veya Integer.MAX_VALUE kullanmak da yaygın bir yaklaşım.
Örnek 3: Diziyi Ters Çevirme
int[] dizi = {1, 2, 3, 4, 5};
int baslangic = 0;
int bitis = dizi.length - 1;
while (baslangic < bitis) {
// Swap (yer değiştir)
int gecici = dizi[baslangic];
dizi[baslangic] = dizi[bitis];
dizi[bitis] = gecici;
baslangic++;
bitis--;
}
// Sonuç: {5, 4, 3, 2, 1}
for (int eleman : dizi) {
System.out.print(eleman + " ");
}İki uçtan başlayıp ortada buluşana kadar yer değiştiriyoruz. Bu "two pointer" tekniği algoritmalarda çok sık karşına çıkacak.
Dizileri Metotlara Geçirme
Diziler referans tipidir. Bir metoda dizi geçirdiğinde, kopyasını değil, orijinalini gönderiyorsun.
public static void main(String[] args) {
int[] notlar = {50, 60, 70};
hepsineEkle(notlar, 10);
// Orijinal dizi değişti!
for (int not : notlar) {
System.out.print(not + " "); // 60 70 80
}
}
static void hepsineEkle(int[] dizi, int miktar) {
for (int i = 0; i < dizi.length; i++) {
dizi[i] += miktar;
}
}Bu davranışı anlamak çok önemli. Metoda int veya double gibi primitive geçirdiğinde kopya gider, orijinal değişmez. Ama dizi geçirdiğinde referans gider, orijinal değişir.
Metottan Dizi Döndürme
static int[] rastgeleDizi(int boyut) {
int[] dizi = new int[boyut];
for (int i = 0; i < boyut; i++) {
dizi[i] = (int)(Math.random() * 100);
}
return dizi;
}
// Kullanım
int[] rastgele = rastgeleDizi(5);
for (int sayi : rastgele) {
System.out.print(sayi + " ");
}String Dizileri
String dizileri tam olarak int dizileri gibi çalışır, ama referans tipi oldukları için null olabilirler.
String[] meyveler = {"Elma", "Armut", "Portakal"};
for (String meyve : meyveler) {
System.out.println(meyve + " (" + meyve.length() + " harf)");
}Çıktı:
Elma (4 harf)
Armut (5 harf)
Portakal (8 harf)null Kontrolü
String[] isimler = new String[3];
isimler[0] = "Ali";
// isimler[1] ve isimler[2] null
for (String isim : isimler) {
if (isim != null) {
System.out.println(isim.toUpperCase());
} else {
System.out.println("(boş)");
}
}null olan bir String üzerinde metot çağırırsan NullPointerException alırsın. Her zaman kontrol et.
Komut Satırı Argümanları (args)
main metodundaki String[] args aslında bir String dizisi! Programa dışarıdan veri göndermek için kullanılır.
public class Selamlama {
public static void main(String[] args) {
if (args.length > 0) {
System.out.println("Merhaba, " + args[0] + "!");
} else {
System.out.println("Merhaba, dünya!");
}
}
}$ java Selamlama Ali
Merhaba, Ali!
$ java Selamlama
Merhaba, dünya!Her main metodunda gördüğün args artık sana yabancı değil — o sadece bir String dizisi.
Dizinin Kopyalanması
Dizi atamak kopya oluşturmaz! Sadece aynı diziye yeni bir referans ekler.
int[] orijinal = {1, 2, 3};
int[] kopya = orijinal; // BU KOPYA DEĞİL!
kopya[0] = 99;
System.out.println(orijinal[0]); // 99 — orijinal de değişti!Gerçek kopya yapmak için:
int[] orijinal = {1, 2, 3};
// Yol 1: Döngü ile
int[] kopya1 = new int[orijinal.length];
for (int i = 0; i < orijinal.length; i++) {
kopya1[i] = orijinal[i];
}
// Yol 2: Arrays.copyOf (tercih edilen)
int[] kopya2 = Arrays.copyOf(orijinal, orijinal.length);
// Yol 3: clone
int[] kopya3 = orijinal.clone();Arrays.copyOf kullanımını bir sonraki derste detaylı göreceğiz. Şimdilik "dizi atamak kopya yapmaz" kuralını aklına kazı.
Dizileri Yazdırma
Diziyi direkt println ile yazdırmaya çalışırsan sürprizle karşılaşırsın:
int[] notlar = {90, 85, 72};
System.out.println(notlar); // [I@15db9742 — bu ne?!Bu çıktı dizinin bellek adresini gösteriyor. İçeriğini görmek için:
import java.util.Arrays;
int[] notlar = {90, 85, 72};
System.out.println(Arrays.toString(notlar)); // [90, 85, 72]Arrays.toString() dizinin içeriğini güzel formatlı bir String'e çevirir. Debug yaparken hayat kurtarır.
Yaygın Hatalar ve İpuçları
Hata 1: Dizi boyutunu değişken ile karıştırmak
int[] dizi = new int[5];
dizi[5] = 10; // HATA! Son indeks 4Hata 2: Diziyi başlatmadan kullanmak
int[] dizi;
dizi[0] = 5; // HATA! dizi henüz oluşturulmadı (null)Hata 3: for-each ile eleman değiştirmeye çalışmak
for (int x : dizi) {
x = x * 2; // orijinal dizi DEĞİŞMEZ
}Hata 4: == ile dizi karşılaştırmak
int[] a = {1, 2, 3};
int[] b = {1, 2, 3};
System.out.println(a == b); // false (referans karşılaştırır)
System.out.println(Arrays.equals(a, b)); // true (içerik karşılaştırır)Özet
Dizi, aynı türden sabit sayıda elemanı bellekte yan yana tutan veri yapısıdır
İndeksler 0'dan başlar, son indeks
length - 1'dirfor-eachile okuma, klasikforile okuma + yazma yapılırVar olmayan indekse erişim →
ArrayIndexOutOfBoundsExceptionDizi referans tipidir: metoda geçince orijinal değişir,
=ile atamak kopya yapmazİçeriği yazdırmak için
Arrays.toString(), karşılaştırmak içinArrays.equals()kullan
AI Asistan
Sorularını yanıtlamaya hazır