Javada Diziler
Javada diziler
Dizi, belli bir sayıda ve aynı veri türünden değişkenlere, aynı isim altında erişilmesini sağlayan bir referanstır.
Aslında bu tanım içerisinde çok geniş kavramlar var ve açıklanması gerekli. Herşeyden önce, dizilerin referans olduklarını söylüyor. Java dilindede, C#�ta olduğu gibi diziler referans tipli verilerdir. Dolayısıyla bir dizi, belleğin yığın (stack) kısmında tutulurken, dizi elemanlarının tamamı, öbek (heap)�te yer alır. Yani dizinin adı, öbekteki elemanların başlangıç adresine işaret eder. Bu dizilerin en önemli unsurlarından birisidir. Diğer yandan, diziler aynı veri türünden elemanlara sahip olmalıdır. Bununla birlikte dizilerin eleman sayısıda oluşturulurken belirlenir. Dolayısıyla, bir diziyi en baştan boyutlandırdığımızda, beliltilen sayıda elemanı aktarabiliriz ve buda dizinin boyutu ile dinamik olarak oynamamızı engeller. Doğruyu söylemek gerekirse bu kısıtlamalar belkide C# dilinde koleksiyonları geliştirilmesine ve daha çok önem kazanmasına neden olmuştur. Kimbili belki Java dilinde�de koleksiyonlar var. Şimdilik karşıma çıkmadılar.
O halde işe referans veri tipi olan dizilerin nasıl tanımlanacağından başlamak gerekiyor. Referans tipli olması, dizilerin oluşturulurken new yapılandırıcı kullanılarak oluşturulması gerektiği sonucunu ortaya çıkartıyor. Nitekim, diziler referans tipli nesnelerdir. Dolayısıyla bir sınıf örneği olmak zorundalar. Ancak diğer yandan, bir diziyi oluştururken new yapılandırıcısını kullanmak zorunda değiliz. Dizi elemanlarına, 0 tabanalı bir indis sistemi ile erişebilmekteyiz. Bu anlamda dizilerin, döngüler ile kardeş olmalarını gayet iyi anlayabiliyorum. Şimdi dizi kavramını incelemek için basit ama hızlı bir örnek geliştirmek düşüncesindeyim. Kahvemden bir yudum alıyorum ve aşağıdaki örneği yazıyorum.
public class Dizi
{
public static void main(String[] args)
{
int dizi1[]=new int[10];
for(int i=0;i<dizi1.length;++i)
{
dizi1[i]=i*2;
System.out.println((i+1)+". eleman="+dizi1[i]);
}
}
}
Uygulamayı başarı ile derledikten sonra çalıştırdığımda aşağıdaki sonucu aldım.
Kodların çalışma sistematiği oldukça basit. Diziyi tanımlaka için new yapılandırıcısını kullandık ve dizinin integer veri tipinden 10 elemanlı olmasını sağladık. Bu noktadan sonra dizimize elemanlar atamak için bir döngü kullandık. Bu döngü dizimizin boyutuna kadar hareket eden ve her bir elemana indis değerinin iki katını aktaran bir yapıda. Kullandığımız length özelliği, dizilerin boyutunu elde etmekte kullanılmakta. Buradanda zaten, dizilerin bir Java sınıfına ait olduğu sonucuna varabiliriz. Kodumuzda, dizi elemanlarını okumak içinde aynı döngü içindeki dizi1[i] şeklindeki yazımı kullandık. Dizileri yukarıdaki örnekte olduğu gibi new yapılandırıcısı ile tanımlayabileceğimiz gibi, başka alternatif bir yoluda kullanabiliriz. Benzer bir örnek uygulam aşağıda yer alıyor.
public class Dizi2
{
public static void main(String[] args)
{
int[] dizi={1,3,5,7,9,11,13,15};
for(int i=0;i<dizi.length;++i)
{
System.out.println((i+1)+". eleman="+dizi[i]);
}
}
}
Burada diziyi tanımlarken elemanlarınıda baştan atamış olduk. Bu aynı zamanda verdiğimiz eleman sayısına göre dizinin otomatik olarak boyutlandırıldığınıda göstermektedir. Son örneğimizin bellekteki yerleşim planına göz atarsak aşadıdaki tasvire benzer bir yapının oluştuğunu görürüz.
Peki ya bir diziye taımlandığı veri tipinden başka bir tipte eleman eklemeye kalkarsak ne gibi sonuçlarla karşılaşabiliriz. Doğrusu bunu merak ediyorum. Bu nedenle yukarıdaki örnekte, integer tipteki dizimize, başka bir veri tipinden eleman eklemeye karar verdim. Bu amaçla, �a� karakterini sincizce dizi elemanları arasına yerleştirdim.
public class Dizi2 |
Uygulamayı derlediğimde her hangibi hata mesajı ile karşılaşmadım. Diğer yandan uygulamayı çalıştırdığımda aşağıdaki hata mesajı beni bekliyordu.
Vouv! Hiç beklemediğim bir durum. 7nci eleman yani �a� değerinin karakter karşılığı oluvermişti bir anda. Hımm. Aslında bu istemediğim bir sonuç. Ben daha çok bir hata mesajı bekliyordum. Yoksa dizi tanımında bir tanımlama hatasımı yaptım? Denemeye devam etmeye karar verdim. Sabahın kaçı olursa olsun ben bu hata mesajını bulacaktım. Kodları aşağıdaki şekilde değiştirdim. Aklıma ilk gelen integer değilse bir double değeri buraya koymak oldu. Hatta bir tane değil bir kaç farklı veri tipinden değerler koymak.
public class Dizi2 |
Sonunda başardım. İstediğim hata mesajlarını aldım ve dizi tanımına sadık kaldım.
Ancak dizileri kullanırken başıma gelebilecek diğer hatalarıda incelemek istiyorum. Öncelikle dizide olmayan bir indis elemanı oluşturmak istersem veya ona ulaşmak istersem ne olur? Fazla söze gerek yok hemen kodları yazmak lazım. Bu kez 5 elemanlı bir diziye 6ncı elemanı eklemeye çalışacağım.
public class Dizi2 |
Uygulama yine hatası olarak derlendi. Umarım bu sefer çalıştırdığımda istediğim hatayı alabilirim. Evet. Mükemmel. Hatayı elde etmeyi başardım.
Dizileri tanımlarken, aynı veri türünden elemanları grupladığımızdan bahsetmiştik. Farklı bir durum daha vardır. Bu da bir diziyi Java dilinin en üst sınıf olan (C# taki gibi) Object türünden tanımlamak ve elemanları birer nesne olarak belirlemektir. Bu teknikte, dizinin tüm elemanları birer nesnedir. Bu anlamda bellekteki dizilişte farklı olmaktadır. Öyleki, Object türünden bir dizi tanıladığımızda, dizinin elemanları öbekte tutulurken her bir eleman nesne olduğu için, yine öbekteki asıl alanlarına referans eden değerleri taşırlar. Ancak dizi elemanlarına eriştiğimizde, bu nesnelerin referans ettikleri öbek alanlarındaki verilere ulaşılır. Hemen bununla ilgili bir örnek yapmakta fayda var.
public class DiziObject |
Burada yaptığım Object türünden dizim için, new yapılandırıcılarını kullanarak sırasıyla integer, string, double ve boolean veri türlerinden birer nesne yaratmak ve daha sonra bu nesneleri Object türünden diziye aktarmak. Uygulama başarılı bir şekilde derlenicektir ve çalışacaktır.
Bu tekniğin bellekteki görünümü ise aşağıdaki tasvire benzer şekilde olucaktır.
Tabi burada aynı örneği aşağıdaki şekide geliştirmeyide düşündüm ama bu durumda hata mesajları ile karşılaştım. Çünkü aşağıdaki tekniği uygulayarak bir Object dizisi oluşturmaya çalıştığımda, elemanların her biri birer değişken olarak algılandı ve Object dizisine eklenmeye çalışılmak istendi. Ancak Object türünden bir dizi, kendisi gibi nesne elemanlarını kabul edeceğinden temel veri türlerinden tanımlanmış değişlenleri kabul etmedi ve derleyici bir sürü hata mesajı verdi.
public class DiziObject |
Ancak burada dikkat etmemiz gereken bir nokta var. O da, String tipteki "Ben bir stringim" için bir hata mesajı almamış olmamız. Bunun nedeni aslında çok açık. Nitekim String veri türü, bir referans türüdür. Dolayısıyla new yapılandırıcısı ile bir String nesnesi yaratabiliriz. Bununla birlikte new yapılandırıcısın kullanmadan yukarıdaki gibi bir string tanımlamakta yine aynı işlevi gerçekleştirecektir. Sanırım burada bir dip not olarak şu iki ifadeninde eşit olduklarını söyliyebiliriz.
String s=new String("Merhabar"); | String s="Merhaba"; |
Gelelim diziler ile ilgili ne tür işlevleri gerçekleştirebileceğimize. Dizilerin Java�nın bir sınıfı olduğu söylemiştik. Evet, diziler aslında, java.util.Arrays sınıfının örneklenmiş nesneleridir. Geçen kahve molamdada internetten indirdiğim jsdk dökümanları içinde bu sınıfı aradım ve sayısız pek çok metodunun olduğunu gördüm. Bunların hepsini incelemek için sanıyorumki bir kaç hektar kahve tarlamın olması, bunları öğütücek ve işlemden geçirerek sütlüsünü, 5 şekerlisini çıkartıp bana sunacak bir fabrikam olması gerekiyor. Ama sanıyorumki bu kahve molasında en çok işime yarayacakları incelesem iyi olur. İlk gözüme çarpan aynı isimli metodlardan hemen her veri türü için aşırı yüklenmiş varyasyonların oluşuydu. Örneğin sort metodunu ele alalım. Adındanda anlaşılacağı üzere bu metod dizi elemanlarını sıralıyor. Elbette dizinin tipine bağlı olarak gerçekleştirilen bir sıralama bu. Aşağıdaki örnekte, integer değerlerden oluşan bir diziyi şu metod prototipini kullanarak sıralattım.
public static void sort(int[] a) |
Şimdide kodlarımızı yazalım.
import java.util.*; public class DiziSirala |
Burada öncelikle Arrays.sort metodunu kullanarak sıralam işlemini yapmak için, java.util paketini import anahtar kelimesi ile uygulamamıza ekledik. Bu C# taki namespace�lerin using ifadesi ile eklenmesi ile aynı şey. Integer veri türleri için tasarlanmış bu metodun diğer veri türleri için aşırı yüklenmiş versiyonlarıda mevcut. Burada metodumuz parametre olarak dizinin adını alıyor ve dizinin tipine bakarak uygun olan sort metodunu çalıştırıyor. Sort metodunun bir diğer versiyonuda aşağıda prototipi verilen versiyondur.
public static void sort(int[] a,int fromIndex,int toIndex) |
Bu aşırı yüklenmiş versiyona göre, dizinin sadece belirli indisler arasındaki elemanlarının sıralanmasını sağlamış oluyoruz.Bunu yukarıdaki örneğimize uygularsak;
import java.util.*; |
Bir diğer ilginç metod ise BinarySearch metodu. Sort metodunda olduğu gibi bu metodda diğer tüm veri türleri için aşırı yüklemiş. Prototipi aşağıdaki gibi olan bu metod, dizi içindeki bir elemanın var olup olmadığına bakıyor ve buna göre bir sonuç döndürüyor.
public static int binarySearch(int[] a,int key) |
Şimdi bu metod ile ilgili bir deneme yapmanın tam sırası.
import java.util.*; |
İlk sonuçlar hiçte iç açıcı olmadı benim için. Herşeyden önce aşağıdaki gibi anlamsız bir sonuç elde ettim.
Dökümantasyonu yeniden incelediğimde herşeyin sebebi anlaşılıyordu. BinarySearch metodunu kullanabilmem için, dizinin mutlaka sıralanmış olması gerekiyor. Bu nedenle koda, sort metodunuda ekledim. Bu durumda, dizimizin sıralanmış hali üzerinden arama işlemi başarılı bir şekilde gerçekleştirilmiş oldu. BinarySearch metodunun çalıştırılıması sonucu dönen değer, aradığımız elemanın dizi içindeki indis numarasıdır.
import java.util.*; |
Şimdi daha değişik bir durumu inceleyelim. Eğer dizi içinde olmayan bir eleman ararsak binarySearch metodu nasıl bir sonuç döndürecektir. Bu amaçla aşağıdaki kodu hazırladım. Örnek içinde, iki adet negatif ve iki adet pozitif tamsayıyı dizi içerisinde arattım. Bu elemanların hiçbirisin dizinin bir elemanı değil. Sonuçlara baktığımda dizide olmayan pozifit elemanlar için -12 değerini, dizide olmayan negatif elemanlar için ise -1 değerini elde ettim. Pozifit ve negatif elemanlar için binarySerach metodunun döndürdüğü değerler farklı olmasına rağmen ikise negatiftir. Dolayısıyla negait olmaları dizinin elemanı olmadıklarını göstermektedir.
import java.util.*; |
Demekki binarySearch metodunu bir if koşulu ile kullanarak aranan elemanın dizi içerisinde olup olmadığını belirleyebiliriz.
import java.util.*;
public class DiziBul
{
public static void main(String[] args)
{
int[] dizi={8,6,3,56,12,3,1,0,23,-1,-5};
for(int i=0;i<dizi.length;++i)
{
System.out.println((i+1)+". eleman="+dizi[i]);
}
System.out.println("");
Arrays.sort(dizi);
int sonuc1=Arrays.binarySearch(dizi,156);
if(sonuc1<0)
{
System.out.println("BULUNAMADI");
}
else
{
System.out.println("BULUNDU");
}
}
}