SEN1001 · 6. hafta · Arrays

Diziler (arrays): tanımlama, gezinme, metotlara geçirme

Tek boyutlu dizi oluşturma, varsayılan değerler, length, indeks hataları, enhanced for, toplam/max/ortalama ve dizinin metoda referans olarak gitmesi. Vize sonrası her sınavın temel taşı.

arrayelementindexlengtharray initializerdefault valueArrayIndexOutOfBoundsExceptionenhanced for statementreferencepass-by-valuefrequency countingArrays.toString

Dizi (array), aynı tipte birçok değeri tek bir isim altında, sıralı olarak tutan yapıdır. 30 öğrencinin notu için 30 değişken açmak yerine bir dizi açarsın ve döngüyle gezersin. Vizenin ikinci yarısından itibaren hemen her soru diziyle ilgilidir: indeks takibi, döngüyle gezinme ve “diziyi alan bir metot yaz”.

Altın kurallar:

  1. İndeks 0’dan başlar, son indeks length - 1.
  2. a.length parantezsiz (String’deki length() ile karıştırma).
  3. Yeni dizinin elemanları varsayılan değerle dolar: int için 0.
  4. Enhanced for sadece okumak içindir. Değiştirmek için indeksli for.
  5. Dizi metoda referans olarak gider: metot elemanları değiştirirse çağıran da görür.

Dizi oluşturma

int[] scores = new int[5];        // 5 elemanlı, hepsi 0
scores[0] = 90;
scores[3] = 75;
System.out.println(scores[0] + " " + scores[1] + " " + scores[3] + " " + scores.length);
90 0 75 5
indeks:   0    1    2    3    4
scores: [90] [ 0] [ 0] [75] [ 0]

new int[5] ile dizinin boyutu bir kez belirlenir ve sonradan değişmez. Boyutu değişebilen bir liste lazımsa ArrayList kullanılır (7. hafta).

Varsayılan değerler

double[] d = new double[2];
boolean[] b = new boolean[2];
String[] s = new String[2];
char[] c = new char[2];
System.out.println(d[0] + " " + b[0] + " " + s[0] + " " + (int) c[0]);
0.0 false null 0
Eleman tipiVarsayılan
int, long, short, byte0
double, float0.0
booleanfalse
char'\u0000' (kodu 0 olan karakter)
String ve diğer nesnelernull

Başlangıç listesi (array initializer)

Değerleri baştan biliyorsan:

int[] primes = {2, 3, 5, 7, 11};
System.out.println(primes[0] + " " + primes[4] + " " + primes[primes.length - 1] + " " + primes.length);
String[] days = {"Mon", "Tue", "Wed"};
System.out.println(days[1] + " " + days[1].length());
2 11 11 5
Tue 3

Boyut süslü parantezdeki eleman sayısından çıkar. days[1].length() String’in uzunluğu (3), days.length dizinin uzunluğu (3); biri metot, biri alan (field).

Dizide gezinme

Standart kalıp indeksli for:

for (int i = 0; i < primes.length; i++) {
    System.out.print(primes[i] + " ");
}
System.out.println();
for (int i = primes.length - 1; i >= 0; i--) System.out.print(primes[i] + " ");
2 3 5 7 11 
11 7 5 3 2 

TUZAK · <= ile son indeksi aşmak. for (int i = 0; i <= a.length; i++) son turda a[a.length]’e erişir ve program ArrayIndexOutOfBoundsException: Index 3 out of bounds for length 3 ile çöker. Bu bir runtime error; derleyici yakalamaz.

Diziyi yazdırmak

System.out.println(primes) elemanları basmaz; [I@ ile başlayan bir adres benzeri metin basar (her çalıştırmada farklı olabilir). Hızlıca görmek için:

import java.util.Arrays;
System.out.println(Arrays.toString(primes));
[2, 3, 5, 7, 11]

Sınavda “diziyi yazdır” denirse döngüyle yazmak güvenli yoldur.

Enhanced for (for-each)

int total = 0;
for (int p : primes) total += p;     // "primes'taki her p için"
System.out.println(total);
int[] nums = {1, 2, 3};
for (int x : nums) x = x * 10;       // x kopya, dizi değişmez
System.out.println(Arrays.toString(nums));
for (int i = 0; i < nums.length; i++) nums[i] = nums[i] * 10;
System.out.println(Arrays.toString(nums));
28
[1, 2, 3]
[10, 20, 30]

Enhanced for’da indeks yoktur; her turda sıradaki elemanın değeri değişkene kopyalanır. Okumak için kısa ve hatasız; ama elemanı değiştirmek, indeksi yazdırmak ya da tersten gitmek için indeksli for gerekir.

Temel algoritmalar

public static int sum(int[] arr) {
    int total = 0;
    for (int x : arr) total += x;
    return total;
}
public static int max(int[] arr) {
    int m = arr[0];                       // ilk elemanla başla
    for (int i = 1; i < arr.length; i++) {
        if (arr[i] > m) m = arr[i];
    }
    return m;
}
public static int indexOfMax(int[] arr) {
    int idx = 0;
    for (int i = 1; i < arr.length; i++) {
        if (arr[i] > arr[idx]) idx = i;
    }
    return idx;
}
public static double average(int[] arr) {
    return (double) sum(arr) / arr.length;
}
// main içinde:
int[] data = {4, 9, 2, 9, 7};
System.out.println(sum(data) + " " + max(data) + " " + indexOfMax(data) + " " + average(data));
31 9 1 6.2

indexOfMax iki tane 9 olmasına rağmen 1 döndürdü: > kullandığımız için eşitlikte güncellenmez, ilk görülen kalır. >= yazsaydın 3 dönerdi.

TUZAK · ortalamada int bölme. sum / arr.length iki int; 31 / 5 = 6 olur. Önce (double) cast et: 6.2.

Sıklık sayma (frequency counting)

Değerler küçük bir aralıktaysa (zar 1..6, not 0..10) değeri indeks olarak kullanırsın:

int[] rolls = {3, 1, 3, 6, 2, 3, 6};
int[] freq = new int[7];             // 0..6, 0'ı kullanmıyoruz
for (int r : rolls) freq[r]++;
for (int face = 1; face <= 6; face++) System.out.print(face + ":" + freq[face] + " ");
1:1 2:1 3:3 4:0 5:0 6:2 

Diziyi metoda geçirmek

Dizi değişkeni dizinin kendisini değil, bellekteki yerini (referans, reference) tutar. Metoda dizi verdiğinde bu referansın kopyası gider. Kopya da aynı diziyi gösterdiği için metot elemanları değiştirebilir.

public static void doubleAll(int[] arr) {
    for (int i = 0; i < arr.length; i++) arr[i] *= 2;
}
public static void tryChange(int x) { x = 99; }
public static void reassign(int[] arr) {
    arr = new int[]{9, 9, 9};        // yerel arr başka diziyi gösteriyor artık
    arr[0] = 1;
}
// main içinde:
int[] arr = {1, 2, 3};
doubleAll(arr);
System.out.println(Arrays.toString(arr));
int single = 5;
tryChange(single);
System.out.println(single);
tryChange(arr[0]);                   // tek eleman: int değeri gider
System.out.println(arr[0]);
reassign(arr);
System.out.println(Arrays.toString(arr));
[2, 4, 6]
5
2
[2, 4, 6]
main:   arr ───────┐
                   ▼
                 [2, 4, 6]      doubleAll'daki arr de buraya bakar
                   ▲
doubleAll: arr ────┘

Dört durumu ayır:

ÇağrıNe gider?Çağıranda değişiklik?
doubleAll(arr) elemanları değiştirirreferansın kopyasıEvet
tryChange(single)int değeriHayır
tryChange(arr[0])tek elemanın int değeriHayır
reassign(arr) içinde arr = new ...referansın kopyasıHayır, yerel kopya başka diziye döndü

Java yine pass-by-value çalışıyor; sadece kopyalanan şey bir referans.

Dizi döndüren metot

public static int[] makeSquares(int n) {
    int[] result = new int[n];
    for (int i = 0; i < n; i++) result[i] = i * i;
    return result;
}
// main: System.out.println(Arrays.toString(makeSquares(5)));
[0, 1, 4, 9, 16]

Dönüş tipi int[] yazılır.

Sık yapılan hatalar

Yanlış düşünceDoğrusu
İlk eleman a[1]a[0]
Son eleman a[a.length]a[a.length - 1]
a.length()Dizide parantez yok: a.length
Yeni int dizisi rastgele değerlerle doluHepsi 0
String[] elemanları boş String ""null
for (int x : a) x = 0; diziyi sıfırlarx kopya; indeksli for kullan
int[] b = a; diziyi kopyalarAynı diziyi gösterir
Metot diziyi değiştiremezElemanlarını değiştirebilir
Max için int m = 0;Negatif dizide yanlış; m = arr[0]
System.out.println(a) elemanları basarAdres benzeri metin; döngü ya da Arrays.toString

Kendini test et

Sınavdaki gibi İngilizce sorular. Önce kâğıt kalemle çöz, sonra cevabı aç.

Soru 1kolay

What is printed?

int[] a = new int[4];
a[1] = 5;
a[3] = a[1] * 2;
System.out.println(a[0] + a[1] + a[2] + a[3]);
Cevabı göster
15

new int[4] dört elemanın hepsini 0 yapar. a = {0, 5, 0, 10}. Toplam 0 + 5 + 0 + 10 = 15 (hepsi int, toplama yapılır).

Soru 2orta

What is printed?

int[] a = {10, 20, 30, 40, 50};
System.out.println(a[a.length - 2] + " " + a[1 + 2] + " " + a[a[0] / 10]);
Cevabı göster
40 40 20

length 5, a[3] = 40. a[1 + 2] = a[3] = 40. a[0] / 10 = 1, a[1] = 20. Köşeli parantezin içi önce hesaplanır.

Soru 3kolay

What is printed?

int[] a = {3, 8, 1, 6};
int r = 0;
for (int i = 0; i < a.length; i++) {
    if (a[i] > 4) r += a[i];
}
System.out.println(r);
Cevabı göster
14

4'ten büyük elemanlar 8 ve 6. 8 + 6 = 14.

Soru 4orta

What is printed?

int[] a = {1, 2, 3, 4, 5};
for (int i = 1; i < a.length; i++) a[i] = a[i] + a[i - 1];
System.out.println(Arrays.toString(a));
Cevabı göster
[1, 3, 6, 10, 15]

Her eleman, kendisi ile güncellenmiş önceki elemanın toplamı olur: a[1] = 2 + 1 = 3, a[2] = 3 + 3 = 6, a[3] = 4 + 6 = 10, a[4] = 5 + 10 = 15. Kümülatif toplam (running sum).

Soru 5orta

What is printed?

int[] a = {5, 5, 5};
for (int v : a) v++;
System.out.println(a[0] + a[1] + a[2]);
Cevabı göster
15

Enhanced for'daki v her elemanın kopyasıdır. v++ kopyayı artırır, dizi değişmez. Toplam 5 + 5 + 5 = 15.

Soru 6orta

What is printed?

public static void doubleAll(int[] arr) {
    for (int i = 0; i < arr.length; i++) arr[i] *= 2;
}
// in main:
int[] a = {1, 2, 3};
doubleAll(a);
doubleAll(a);
System.out.println(a[2]);
Cevabı göster
12

Metoda dizinin referansı (adresi) gider; metot aynı diziyi değiştirir. İki çağrıdan sonra her eleman 4 katı: a[2] = 3 * 4 = 12.

Soru 7zor

What is printed?

int[] a = {2, 4, 6};
int x = a[0];
x = 100;
int[] b = a;
b[1] = 100;
System.out.println(a[0] + " " + a[1]);
Cevabı göster
2 100

x = a[0] int değeri kopyalar; x'i değiştirmek diziyi etkilemez. b = a ise yeni dizi oluşturmaz, b ve a aynı diziyi gösterir. b[1] = 100 aslında a[1]'i değiştirir.

Soru 8orta

What is printed?

String[] s = new String[3];
s[0] = "A";
System.out.println(s[0] + s[1]);
Cevabı göster
Anull

String dizisinin varsayılan değeri null. String birleştirmede null, "null" yazısı olarak eklenir: "A" + null = "Anull".

Soru 9orta

What happens when this code runs?

int[] a = {1, 2, 3};
for (int i = 0; i <= a.length; i++) System.out.print(a[i] + " ");
Cevabı göster
Prints 1 2 3 then throws ArrayIndexOutOfBoundsException

Geçerli indeksler 0, 1, 2. i <= a.length koşulu i = 3'ü de dener; a[3] yok. Program önce 1 2 3 basar, sonra Index 3 out of bounds for length 3 ile çöker. Doğrusu i < a.length.

Soru 10orta

What is printed?

int[] a = {7, 3, 9, 3, 1};
int idx = 0;
for (int i = 1; i < a.length; i++) if (a[i] < a[idx]) idx = i;
System.out.println(idx + " " + a[idx]);
Cevabı göster
4 1

En küçük elemanın indeksini tutar. i=1: 3 < 7 → idx 1. i=2: 9 < 3 değil. i=3: 3 < 3 değil (eşitlikte değişmez). i=4: 1 < 3 → idx 4. Sonuç: indeks 4, değer 1.

Soru 11kolay

Write a static method countEven(int[] arr) that returns how many elements of the array are even.

Cevabı göster
for (int x : arr) if (x % 2 == 0) c++; return c;

Sayaç kalıbı dizi üzerinde. Sadece okuduğumuz için enhanced for uygun.public static int countEven(int[] arr) { int c = 0; for (int x : arr) { if (x % 2 == 0) c++; } return c;}Test: {4, 9, 2, 9, 7} → 2.

Soru 12orta

Write a static method max(int[] arr) that returns the largest element. Assume the array is not empty.

Cevabı göster
int m = arr[0]; for (int i = 1; i < arr.length; i++) if (arr[i] > m) m = arr[i]; return m;

Başlangıç değeri dizinin ilk elemanı olmalı. int m = 0; yazarsan tüm elemanları negatif bir dizide yanlış sonuç (0) verir.public static int max(int[] arr) { int m = arr[0]; for (int i = 1; i < arr.length; i++) { if (arr[i] > m) m = arr[i]; } return m;}Test: {4, 9, 2, 9, 7} → 9.

Doğrulama: Tüm çıktılar JDK 26 ile çalıştırıldı (verify/SEN1001/W06.java). Dizi sınırı aşma hatası aynı dosyada yakalanarak (catch) mesajı yazdırıldı.

Deftere not kartı

int[] a = new int[5]; indeksler 0..4 a.length = 5 (parantez YOK; String'de length()) int[] p = {2, 3, 5}; tanım + değerler (new gerekmez) Varsayılan: int 0 double 0.0 boolean false String/nesne null char '\u0000' Son eleman a[a.length - 1] a[a.length] → ArrayIndexOutOfBoundsException Gezinme: for (int i = 0; i < a.length; i++) tersten: i = a.length - 1; i >= 0; i-- Enhanced for: for (int x : a) → sadece OKU; x kopya, x = ... diziyi değiştirmez Toplam: total += a[i] Ortalama: (double) total / a.length Max: m = a[0], sonra i = 1'den; indeks lazımsa idx tut Sıklık: freq[deger]++ println(a) → [I@... (adres) Arrays.toString(a) → [1, 2, 3] (import java.util.Arrays) b = a → KOPYA DEĞİL, aynı dizi; b[0] = 9 a'yı da değiştirir Metoda dizi verirsen metot elemanları değiştirebilir (referansın kopyası gider) Metot içinde arr = new int[...] → çağıranın dizisi değişmez