-
For-each döngüsü
Eşdeğer for döngüsü
for (type var : arr) { body-of-loop }
for (int i = 0; i < arr.length; i++) { type var = arr[i]; body-of-loop }
Bölüm 07
Array Nedir?
Array Yaratma
[] Operatörü
Array'in Bileşenleri
Seçkili (random) Erişim
Array Türleri
Bir Boyutlu Array
Çok Boyutlu Array
Array Arrayi (çentikli array)
Array, aynı tipten çok sayıda değişken tanımlamak için kullanılır. Soyut bir veri yapısıdır. Matematikteki sonlu dizi kavramına benzer. Java dilinde array bir sınıftır. Her sınıfın soyut bir veri tipi olduğunu biliyoruz. Array sınıfı array yaratma, arraylerle işlem yapma, array içinde bileşen arama ve array'in bileşenlerini sıralama gibi array ile ilgili işlemleri yapmaya yarayan öğeleri içeren bir sınıftır.
Array bir sınıf olduğuna göre, bir array'i yaratma bir sınıftan nesne yaratma gibidir. Üç aşaması vardır:
Şimdi bu üç aşamanın nasıl yapıldığını bir örnek üzerinde görelim.
Birinci aşama:
int [] sicilNo ;
deyimi int tipinden sicilNo adlı bir array bildirimidir. Bu aşamada sicilNo null işaret eden bir referanstır (işaretçi, pointer).
İkinci
aşama:
sicilNo = new int[5] ;
kurucu (constructor) deyimi sicilNo tarafından işaret edilen bir nesne yaratır. Başka bir deyişle, ana bellekte (heap içinde) 5 tane int değer tutacak bir yer ayırır. sicilNo bellekte ayrılan bu yeri işaret eder. O nedenle, sicilNo 'ya referans (işaretçi, pointer) denmektedir. O halde, array adları referans tipidir. Başka bir deyişle, array'in adı bir değer değil, kendisine ait nesnenin bellekte bulunduğu adresi işaret eden referanstır.
Yukarıdaki örnekte, arrayin işaret ettiği nesnenin içinde int tipi veri tutacak 5 tane bellek adresi vardır. Bu adresler
SicilNo[0]
sicilNo[1]
sicilNo[2]
sicilNo[3]
sicilNo[4]
adları tarafından işaret (referans) edilirler.
Array adının sonuna gelen [] parantezleri, arrayin bileşenlerini, yukarıda gösterildiği gibi, damgalarıyla (indis, index) belirler.
sicilNo[i] (i=0,1,2,3,4) ler söz konusu nesne içinde birer değişkendir. Bu değişkenler sayesinde, array beş tane int tipi veriyi bir arada tutabilme yeteneğine sahip olur. Bu değişkenlere array'in bileşenleri ya da öğeleri denir. 0,1,2,3,4 sayıları bileşenlerin sıra numaralarıdır; damga (index) adını alırlar. Sıra numaraları (index) daima 0 dan başlar, birer artarak gider. n tane bileşeni olan bir array'in ilk bileşeninin damgası 0, son bileşeninin damgası (n-1) olur. Bir array'in uzunluğu onun bileşenlerinin sayısıdır.
Eğer new int[5] yerine new int[500] yazsaydık, 5 bileşen yerine 500 bileşen elde ederdik.
Arrayin işaret ettiği nesne yaratılınca, onun bileşenleri kendiliğinden başlangıç değeri alırlar. Bunlara öndeğer (default value) denir. Öndeğerler bileşenlerin veri tipine bağlı olarak değişir. Java dilinde bütün sayısal değişkenlerin öndeğerleri daima 0 dır. Boolean tipin öndeğeri false olur. Referans tiplerde ise null olur. O nedenle, yukarıda sicilNo referansının işaret ettiği nesne içindeki SicilNo[0], sicilNo[1], sicilNo[2], sicilNo[3] , sicilNo[4] bileşenlerinin (değişken) öndeğerleri kendiliğinden 0 olur.
Üçüncü aşama:
sicilNo[2] = 1785;
ataması, array'in üçüncü bileşenine 1785 değerini atar.
İstenirse öteki bileşenlere de benzer yolla atamalar yapılabilir.
Yukarıdaki üç aşamayı birleştirerek iki ya da bir adımda hepsini bitirebiliriz. Örneğin,
int [] sicilNo = new int[] {1234, 2746, 1785, 8732, 1079};
deyimi üç aşamayı birden yapar.
İstenirse,
int [] sicilNo = new int[5] ;
deyimi ile ilk iki aşama tamamlanır, bileşenlere değer atama işi sonraya bırakılabilir.
Java dilinde her veri tipinden array yaratılabilir. Örneğin,
String
[] ad = new String [] {“Hilal”, “Esra”,
“Güleda”, “Ali”, “Emrah”};
deyimi String tipinden bir array sınıfı bildirmiş, onun bir nesnesini yaratmış ve o nesnenin bileşenlerine String tipi değerler atamıştır. Bu atama
ad[0] = “Hilal” ; ad[1] = “Esra” ; ad[2] = “Güleda” ; ad[3] = “Ali” ; ad[4] = “Emrah” ;
atamalarına denktir.
Artık, array yaratmak için genel sözdizimini yazabiliriz:
veriTipi [] arrayAdı ; (array bildirimi)
arrayAdı = new veriTipi [bileşen sayısı]; (array nesnesini yaratma)
Array nesnesi yaratmak demek, ana bellekte arryin bileşenlerine birer yer (bellek adresi) ayırmak demektir. Array nesnesi yaratıldıktan sonra onun bileşenlerine değer atama eylemi, diğer değişkenlere değer atama gibidir. İstenen bileşen indeks sayısı ile seçilerek seçkili (random) değer atanabilir. Örneğin, yukarıda yapıldığı gibi,
ad[2] = “Güleda”
deyimi ad adlı arrayin 3-üncü bileşenine “Güleda” değerini atamaktadır.
Array bildiriminde, yukarıda yaptığımız gibi, arrayin uzunluğunu (bileşenlerinin sayısını) nesneyi yaratırken belirtmeliyiz. Ancak, bazı durumlarda, nesneyi yaratırken arrayin uzunluğunu tam bilmiyor olabiliriz. Bu durumda, Array sınıfı yerine ArrayList, LinkedList ya da Vector sınıflarından birisini kullanmalıyız. Tabii, bu sınıfların nitelikleri birbirlerinden farklıdır. Yapmak istediğimiz işe hangisi uyuyorsa onu seçmeliyiz. Örneğin,
short [] sıraNo = new short[];
bildirimi java dilinde geçerli değildir. Derleyici bu bildirime
array dimension missing
hata iletisini yollayacaktır. Onun yerine
short [] sıraNo = new short[28];
gibi, bileşen sayısını belirten deyim yazılmalı ya da { } bloku içinde bileşenlere değerleri atanmalıdır. Tabii, bu şekilde bileşenlere değer atanınca, arrayin uzunluğu (bileşen sayısı) kendiliğinden belli olmaktadır.
Arrayin Bileşenlerine Değer Atama Yöntemleri
Aşağıdaki üç yöntem aynı işi yapar.
1.Yöntem. Arrayin uzunluğunu belirleyip seçkili (random) değer atama
int[] arr;
arr = new int[10];
arr[6]=70; arr[1]=20; arr[2]=30; arr[7]=80; arr[4]=50;
arr[3]=40; arr[0]=10; arr[8]=90; arr[9]=100; arr[5]=60;
deyimi 10 bileşenli bir array yaratır sonra bileşenlerine seçkili (random) değer atar.
2.Yöntem. Nesneyi istemli yaratıp sıralı değerler atama
int[] arr;
arr = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
deyimi 10 bileşenli bir array yaratır ve bileşenlerine sıralı değerler atar. New int[] ifadesi arrayin uzunluğunu belirlemez; ancak {} bloku içine sırayla yazılan değerler array uzunluğunu ve her bileşene atanan değeri kesinkes belirler. {} içindeki değerlerin yazılış sırası ile bileşenlerin sırası uyumludur. Örneğin, {} içindeki 7-inci değer 7-inci bileşene aittir. Tabii, 7-inci bileşenin damgasının 6 olduğunu biliyoruz; çünkü damgalama işlemi 1 den değil 0 dan başlar. O nedenle arr[6] = 70 dir. Arraylerde bu özeliği daima anımsamalıyız.
3.Yöntem. Nesneyi istemsiz yaratıp sıralı değerler atama
int[] arr { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
deyimi yukarıdaki deyimin yaptığı işin aynısını yapar; ancak new operatörünü istemli (explicit) kullanmaz, nesne istemsiz (implicit) olarak yaratılır.
Arrayin Uzunluğunu Bulma
Java dilinde bir arrayin uzunluğunu bulmak için length özgenini (attribute) kullanırız. Çoğumuz array uzunluğunu bulan bir metot (fonksiyon) olması gerektiğini sanabiliriz. Ama length bir metot değil, bir özgendir ve arrayin uzunluğunu belirlememize yarar.
ArrayUzunluğu.java
public class ArrayUzunluğu
{
public static void main(String[] args)
{
String[] meyve = {"elma", "çilek", "kiraz"};
int arrayUzunluğu = meyve.length;
System.out.format("Bileşen sayısı: %d ", arrayUzunluğu);
}
}
Çıktı:
Bileşen sayısı: 3
Array bileşenlerine değer atama eylemi, genellikle program koşarden dinamik olarak yapılır. Aşağıdaki iki örnekte, bir döngü ile array bileşenlerinin bazılarına değer atanmaktadır. Sonra başka bir döngü ile bütün bileşenlerin değerleri konsola yazdırılmaktadır. Değer atanmamış bileşenlerin (default) değerlerinin 0 olduğuna dikkat ediniz.
Array01.java
class Array01
{
public static void main(String[] args)
{
int[] çarpan = new int[10];
for (int i = 6; i < 10; i++)
{
çarpan[i] = i * i;
}
for (int i = 0; i < 10; i++)
{
System.out.print(çarpan[i]);
System.out.print("\t");
}
}
}
Çıktı:
0 0 0 0 0 0 36 49 64 81
Array02.java
class Array02
{
public static void main(String[] args)
{
int[] intSayı = new int[5];
for (int i = 0; i < intSayı.length; i++)
intSayı[i] = i * 10;
for (int i = 0; i < intSayı.length; i++)
System.out.println("intSayı[" + i + "] = " + intSayı[i]);
}
}
Çıktı
intSayı[0] = 0
intSayı[1] = 10
intSayı[2] = 20
intSayı[3] = 30
intSayı[4] = 40
Arrayin bileşenleri değişken olduklarından, onlara istendiğinde değer atanabileceği, istenirse atanan değerlerin değiştirilebileceği açıktır. Yukarıdaki sicilNo[2] = 1785 atama deyimi, arraylerin üstün bir niteliğini ortaya koyar. Arrayin istenen bileşenine damga (indeks) sayısı ile doğrudan (seçkili, random) erişmek mümkündür. Her bileşen bir değişken olduğu için, o bileşen tipiyle yapılabilen her işlem onlar için de yapılabilir, değişkenlerle ilgili kurallar bileşenler için de aynen geçerlidir. SicilNo[2] = 1785; deyimi indeksi 2 olan bileşene 1785 değerini atamıştır.
Bileşen değerleri aynı veri tinden başka değişkenlere aktarılabilir ve tabii bu işin tersi de yapılabilir. Örneğin, x aynı tipten bir değişken ise
x = sicilNo[2];
ataması, sicilNo[2] bileşeninin değerini x değişkenine aktarır; öyleyse, bu atama deyimi
x = 1785 ;
atamasına denktir.
Tersine olarak, y aynı tipten bir değişken ise değeri bileşene ktarılabilir. Örneğin,
int y = 123;
sicilNo[2] = y;
ataması geçerlidir. Bu atama y nin değerini sicilNo[2] bileşenine aktarır; dolayısıyla,
sicilNo[2] = 123;
atamasına demktir.
Bir arrayin bir bileşeninin değeri başka bir bileşenine aktarılabilir. Örneğin,
sicilN0[3] = sicilNo[2];
ataması geçerlidir.
Aynı veri tipinden iki arrayden birisinin bir bileşeninin değeri ötekinin bir bileşenine aktarılabilir. Örneğin,
short[] a,b ;
a = new short[] {10,20,30};
b[2] = a[0];
ataması geçerlidir.
Aynı veri tipinden iki arrayden birisi ötekine aktarılabilir. Örneğin,
short[] a,b ;
a = new short[] {10,20,30};
b = a ;
ataması geçerlidir. Bu atama, b referansının a ile aynı yeri işaret etmesinei sağlar. Dolayısıyla, aşağıdaki bileşen atamalarının birer birer yaptığı işi tek başına yapar.
b[0] = a[0];
b[1] = a[1];
b[2] = a[2];
Tabii, burada bir arrayi ötekine aktarmanın, bileşenleri tek tek aktarmaktan çok daha kolay olduğunu görüyoruz.
Aşağıdaki örnek, bileşenlerle işlem yapılabileceğini göstermektedir. Aylık ücretler ve gelir vergileri iki ayrı array ile tutulmakta, bir döngü ile %30 gelir vergisi hesaplanıp konsola yazılmaktadır.
VergiHesapla.java
class VergiHesapla
{
public static void main(String[] args)
{
double[] aylıkÜcret = new double[3];
aylıkÜcret[0] = 2782.45;
aylıkÜcret[1] = 9346.74;
aylıkÜcret[2] = 10867.83;
double[] gelirVergisi = new double[3];
for (int i = 0; i < aylıkÜcret.length; i++)
{
gelirVergisi[i] = aylıkÜcret[i] * 30 / 100;
System.out.println("Aylık " + aylıkÜcret[i] + " TL ücretin gelir vergisi = " + gelirVergisi[i]);
}
}
}
Çıktı
2.782,45 TL ücretin gelir vergisi = 834,74 TL
9.346,74 TL ücretin gelir vergisi = 2.804,02 TL
10.867,83 TL ücretin gelir vergisi = 3.260,349 TL
Arrayin bileşenlerden başka değişkenlere ya da başka değişkenlerden arrayin bileşimlerine veri aktarmalarında istemli (explicit) ve istemsiz (implicit) dönüşüm kuralları aynen geçerlidir. Aşağıdaki program short tipinden int tipine istemsiz dönüşüm yapılabileceğini göstermektedir.
Array04.java
class Array04
{
public static void main(String[] args)
{
short[] a = { 1, 2, 3, 4 };
int[] b = { 5, 6, 262141, 8, 9 };
System.out.println("b[2] = " + b[2]);
b[2] = a[3];
System.out.println("b[2] = " + b[2]);
}
}
Çıktı
b[2] = 262141
b[2] = 4
Aynı aktarmayı tersinden yapmak isteyelim. Yukarıdaki programda b[2] = a[3] deyimi yerine a[2] = b[3] yazarsak, derleyiciden şu hata mesajını alırız:
... java:8: possible loss of precision
Bu hata mesajı bize programın 8-inci satırında yapılan a[2] = b[3] atamasında veri kaybı olacağını söylüyor. Çünkü 8-inci satırda yaptığımız bu atama ile 32 bitlik bir adrese yazılan int değerini 16 bitlik bir adrese yazılan short tipine aktarmak istedik.
Derleyicinin istemsiz (implicit casting) yapmadığı dönüşümü zorla yaptırmak istersek, istemli dönüşüm (explicit casting) yapabiliriz:
Array05.java
class Array05
{
public static void main(String[] args)
{
short[] a = { 1, 2, 3, 4 };
int[] b = { 5, 6, 262141, 8, 9 };
System.out.println("a[3] = " + a[3]);
a[3] = (short)b[2];
System.out.println("a[3] = " + a[3]);
}
}
Çıktı
a[3] = 4
a[3] = -3
Gerçekten derleyicinin verdiği tehlike uyarısı burada gerçekleşmiş oluyor. 8-inci satırda a[3] bileşenine 262141 değerini istemli (exlicit) aktarıyoruz. Ama aktardığımız sayı 16 bitlik adrese sığmadığı için, sığmayan (alt) bitler atılıyor ve adrese 262141 yerine -3 sayısı yazılıyor.
Uyarı:
Arrayler çok sayıda değişken tanımlama ve bileşenlerine doğrudan istemli erişim sağlamaları yanında, döngüleri de çok kolaylaştırırlar. Aşağıdaki program foreach döngüsünün arraylere nasıl uygulanacağını göstermektedir.
Array06.java
class Array06
{
public static void main(String[] args)
{
int[] arr = { 11, 12, 13, 14, 15, 16, -21, -11, 0 };
for (int i : arr)
{
System.out.print(i + " \t " );
}
}
}
Çıktı
11, 12, 13, 14, 15, 16, -21, -11, 0
Aşağıdaki program, bir metotla değer yazdırmakta, başka bir metotla değer okutmaktadır. Metotların parametreleri yaratılan array nesnedir.
Array07.java
class Array07
{
static int n = 10;
static int[] arr = new int[n];
static void değerYaz(int[] p)
{
for (int i = 0; i < p.length; i++)
p[i] = i;
}
static void değerOku(int[] r)
{
for (int i = 0; i < r.length; i++)
System.out.println(r[i]);
}
public static void main(String[] args)
{
değerYaz(arr);
değerOku(arr);
}
}
Çıktı:
0
1
2
3
4
5
6
7
8
9
Array istemsiz (implicit) olarak java.lang.Object sınıfından türetilir; dolayısyla Object sınıfının bütün özeliklerine sahiptir.
Java'da array'in avantajları şunlardır:
İlkel veri tiplerinin hepsinden array yaratılabilir.
Arrayin uzunluğu (bileşen sayısı) belirlidir.
Array kendi veri tipini bilir; o tiplerle yapılabilen bütün işlemlere izin verir. Bileşenlere yapılan atamalar derleme anında denetlenir; varsa hata mesajı gelir.
Java'da array'in avantajları şunlardır:
arrayin uzunluğu kessinkes sabittir; değiştirilemez. [Arrayin uzunluğu önceden bilinemiyorsa, array yerine Vector ya da ArrayList kullanılmalıdır.]
Arrayin bütün bileşenlerine ancak aynı tipten veri atanabilir. [Farklı veri tipleri ile uğraşmak gerekiyorsa, array yerine Collection kullanılmalıdır.]
Uygulamalar
Aşağıdaki program for döngüsü ile 1 den 100 e kadar tamsayıları toplamakta ve toplamı ekrana yazmaktadır.
Toplam.java
public class Toplam
{
public static void main(String[] args)
{
int[] x = new int [101];
for (int i = 0; i<x.length; i++ )
x[i] = i;
int Toplam = 0;
for(int i = 0; i<x.length; i++)
Toplam += x[i];
System.out.println(Toplam);
}
}
ArrayKopyala.java
/* Bu program
* arrayopy() metodunu kullanmaktadır
*/
public class ArrayKopyala {
public static void main(String[] args){
char[] neredenKopya = {'a','b','c','d','e','f','g','h','i','j'};
char[] nereyeKopya = new char[5];
System.arraycopy(neredenKopya, 2, nereyeKopya, 0, 5);
System.out.println(new String (nereyeKopya));
}
}
For-each Döngüsü
Bir arrayin bütün bileşenlerini sırayla istenen bir işleme sokan döngüye for-each (enhanced for) döngüsü denilir. Bu döngü for döngüsünün yaptığı işi yapar. Sözdizimi daha kısa ve kolaydır. Aşağıdaki tablo iki döngünün sözdizimlerini karşılaştırmaktadır.
For-each döngüsü |
Eşdeğer for döngüsü |
---|---|
for (type var : arr) { body-of-loop } |
for (int i = 0; i < arr.length; i++) { type var = arr[i]; body-of-loop } |
Örnekler:
public class ForArray {
public static void main(String[] args){
int[] squares = {0,1,4,9,16,25};
for (int i=0; i< squares.length; i++){
System.out.printf("%d nin karesi %d dir.\n",i, squares[i]);
}
}
}
Çıktı:
0 nin karesi 0 dir.
1 nin karesi 1 dir.
2 nin karesi 4 dir.
3 nin karesi 9 dir.
4 nin karesi 16 dir.
5 nin karesi 25 dir.
Bölüm
07 : Array