Dizilere uygulanabilecek işlemlerin eleman erişim ve güncelleme ile uzunluk sorgulamaya sınırlı olması, size Java'da bir şeylerin eksik olduğunu düşündürebilir. Java platformu tasarımcıları da bu görüşü paylaşıyor olmalılar ki,
Kopyalama işlemi ile başlayalım. Dizileri tanıttığımız yazıdan🔎 da hatırlayacağınız gibi, dizi türlü bir değişkenin bir diğerine atanması, etkisini tutacaklar aracılığıyla göstereceği için kopyalama değil paylaşmaya neden olacaktır; kopyalama döngü içinde her elemanın teker teker kopyalanması ile mümkündür. Ancak, standart olmayan bu çözümün yerine, ilk argümanındaki dizinin başlangıcından itibaren ikinci argümandaki kadar elemanı kopyalayan ve çıkardığı kopyanın tutacağını döndüren
Bileşke türlü değerlerin Java'da tutacak ve nesne olmak üzere iki parça ile temsil edildiğini unutanları şaşırtacak bir diğer işlem eşitlik denetimidir. Ancak,
Eşitlik denetimi için öne sürülen sebepten ötürü, hoş yazım ve kıyım işlemleri1 de metot çiftleri ile karşılanır:
Değineceğimiz bir sonraki metot, belki de gezegenimizdeki kurulu bilgisayar sistemlerinin işlemcilerini en çok meşgul eden arama işleminin gerçekleştirimini sağlar. Algoritma derslerinden tanıdık ikili aramayı gerçekleştiren
İkili aramanın hünerini sıralı bir dizi üzerinde göstermesi, dizinin sıralı bir şekilde oluşturulması veya ikili arama öncesinde sıralanması zorunluluğunu da beraberinde getirir. Programcıya yüklenen bu sorumluluk,
Göz atacağımız son metot olan
java.util
paketindeki Arrays
sınıfı vasıtasıyla epey geniş bir işlevsellik sunmuşlar. İşte bu yazıda yapacağımız, anılan sınıf tarafından sağlanan ve değişik eleman türlerine göre ezilmiş metotlara bakmak olacak.Kopyalama işlemi ile başlayalım. Dizileri tanıttığımız yazıdan🔎 da hatırlayacağınız gibi, dizi türlü bir değişkenin bir diğerine atanması, etkisini tutacaklar aracılığıyla göstereceği için kopyalama değil paylaşmaya neden olacaktır; kopyalama döngü içinde her elemanın teker teker kopyalanması ile mümkündür. Ancak, standart olmayan bu çözümün yerine, ilk argümanındaki dizinin başlangıcından itibaren ikinci argümandaki kadar elemanı kopyalayan ve çıkardığı kopyanın tutacağını döndüren
Arrays.copyOf
metodunun kullanılması yerinde olacaktır.import java.util.Arrays; ... Integer[] tekler = new Integer[] {1, 3, 5, 7, 9}; Integer[] tKopya = Arrays.copyOf(tekler, tekler.length);Benzer bir işleve sahip
Arrays.copyOfRange
, ikinci ve üçüncü argümanlarının işaret ettiği indisler arasındaki dilimi kopyalayarak işini görür. Dolayısıyla, Arrays.copyOf
ile Arrays.copyOfRange
arasında şu denklik kurulabilir.Arrays.copyOf(dz. i) ≡ Arrays.copyOf(dz, 0, i)
Bileşke türlü değerlerin Java'da tutacak ve nesne olmak üzere iki parça ile temsil edildiğini unutanları şaşırtacak bir diğer işlem eşitlik denetimidir. Ancak,
==
ile işin olmayacağını bilip şansını equals
iletisi ile denemek isteyenler için de sonuç hayal kırıklığı olacaktır. Bu durumun nedeni dizi türlerinin Java programlama dili tarafından ele alınışında yatar: eleman sayısını dizinin türünü belirlemekte kullanmayan Java derleyicisi, her farklı eleman türü için, programcı tarafından doğrudan erişilemeyen ve Object
sınıfından kalıtlayan özel bir sınıf sentezler. Bu bilgi, sentezlenen sınıflarda Object
'teki equals
gerçekleştiriminin ezilmediği bilgisiyle birleştirildiğinde, equals
kullanımının neden derdimize çare olmadığı görülecektir: dizi nesnelerine equals
iletisinin gönderilmesi Object
'te sağlanan ve ==
ile aynı şekilde çalışan metodun işlemesine neden olacaktır. Bir diğer deyişle, dizi nesneleri için equals
ile ==
arasında bir fark yoktur. O zaman, ne yapmamız gerek? Yanıt, Arrays
sınıfındaki iki metottan birini kullanmaktan geçer. Bunlardan ilki, tek boyutlu dizilerin eşitlik denetimini yapan Arrays.equals
metodudur.boolean eşitMi = tekler == tKopya; // eşitMi ← false eşitMi = tekler.equals(tKopya); // eşitMi ← false eşitMi = Arrays.equals(tekler, tKopya); // eşitMi ← true
Arrays.equals
metodunun neden tek boyutlu dizilere sınırlı olduğunu, çok boyutlu dizilerin Java'da nasıl temsil edildiğine bir kez daha değinerek açıklık getirelim: Java'da çok boyutlu diziler, elemanları dizi olan diziler şeklinde tutulur. Dolayısıyla, dizinin elemanlarına equals
iletisini göndermek suretiyle işini gören Arrays.equals
metodunun çok boyutlu diziler için iş görmesi olanaksızdır. Bunu, aşağıdaki kod parçası üzerinden görelim.char[][] bulmaca = new char[10][12]; char[][] bulmaca2 = new char[10][12]; // Dizileri eşit içeriğe sahip olacak şekilde doldur eşitMi = Arrays.equals(bulmaca, bulmaca2); // eşitMi ← false eşitMi = Arrays.deepEquals(bulmaca, bulmaca2); // eşitMi ← trueYukarıdaki dizilerin eşitlik denetimi için
Arrays.equals
metodunun kullanılması, dizilerin eleman türü olan ve derleyici tarafından sentezlenen char[]
sınıfındaki equals
metodunun kullanılması ile işini görecektir. Bu ise, söz konusu metodun ==
ile aynı şekilde çalışması nedeniyle, dizilerin karşılıklı elemanlarının eşitlik yerine aynılık denetimi yapılarak kontrol edilmesi anlamına gelir ve beklediğimiz sonucu vermez. Çözüm, Arrays.deepEquals
metodunun kullanımından geçer.Eşitlik denetimi için öne sürülen sebepten ötürü, hoş yazım ve kıyım işlemleri1 de metot çiftleri ile karşılanır:
Arrays.toString
, Arrays.deepToString
ve Arrays.hashCode
, Arrays.deepHashCode
.Arrays
sınıfında yer alan bir diğer metot, kendisine geçirilen dizinin elemanlarını aynı değer ile doldurmaya yarayan fill
metodudur. Bu metot, dizinin tümü ve bir dilimi üzerinde etkisini gösteren iki farklı uyarlamaya sahiptir ve bu uyarlamalar aşağıdaki denklikle ilişkilendirilebilir.Arrays.fill(dz. i) ≡ Arrays.fill(dz, 0, dz.length, i)
Değineceğimiz bir sonraki metot, belki de gezegenimizdeki kurulu bilgisayar sistemlerinin işlemcilerini en çok meşgul eden arama işleminin gerçekleştirimini sağlar. Algoritma derslerinden tanıdık ikili aramayı gerçekleştiren
Arrays.binarySearch
metodu, ilk argümanında sağlanan elemanları artan sırada dizilmiş dizinin içinde bir anahtar değerin geçip geçmediğine bakar. Denetim sonucunun olumlu olması durumunda, anahtarın geçtiği dizi elemanının indisi döndürülür;2 aramanın başarısız olması durumunda ise, anahtarın sırayı bozmayacak şekilde diziye eklenmesi halinde eklemenin yapılacağı indisin -1 ile çarpımından 1 çıkarılması sonucu elde edilen değer döndürülür. Daha hızlı sonuç elde edilmesi amacıyla, arama dizinin belirli bir dilimine sınırlandırılabilir. Tüm dizi ve dizi dilimi üzerinde çalışan uyarlamalar arasındaki ilişki aşağıda verilmiştir.Arrays.binarySearch(dz. anahtar)
≡
Arrays.binarySearch(dz, 0, dz.length, anahtar)
Arrays.binarySearch
metodunun bileşke türlü elemanlara sahip bir dizide arama yapması öncesinde, ilişkin türe dair sınıfın gerçekleştiriminde equals
metodunun uygun bir biçimde sağlanmış olmasına dikkat edilmelidir. Aksi takdirde, dizide var olan bir anahtarın bulunmadığının ilan edilmesi gibi bir hata ortaya çıkabilir. Böylesine bir durumun önüne geçmek için başvurulacak ikinci bir yol, java.util.Comparator
arayüzünü gerçekleştiren karşılaştırıcı bir sınıfta equals
iletisinin gerçekleştirilmesi ve bu sınıfın bir nesnesinin diğer argümanların ardından son argüman olarak Arrays.binarySearch
'e geçirilmesidir.İkili aramanın hünerini sıralı bir dizi üzerinde göstermesi, dizinin sıralı bir şekilde oluşturulması veya ikili arama öncesinde sıralanması zorunluluğunu da beraberinde getirir. Programcıya yüklenen bu sorumluluk,
Arrays.sort
metodu ile hafifletilebilir. İsteğe göre dizinin tümü veya belirli bir dilimini sıralayan bu metot, dizinin eleman türünün karşılaştırılabilir olmasını bekler. Bu ise, bileşke türler için ilişkin sınıfın Comparable
arayüzünü gerçekleştirmesi ve/veya karşılaştırma ölçütünün java.util.Comparator
arayüzünü gerçekleştiren bir sınıf vasıtasıyla söz konusu işlevselliğin sağlanması gerektiği anlamına gelir.Arrays.sort(dz) ≡ Arrays.sort(dz, 0, dz.length)
Göz atacağımız son metot olan
Arrays.asList
, yegâne argümanındaki diziyi Veri Kapları Çerçevesi'nce tanımlanan java.util.List
ve java.util.RandomAccess
arayüzlerine sahip bir nesneye çevirir ve bu nesneyi gösteren bir java.util.List
tutacağı döndürür. Nesneye gönderilen iletilerin diziyi de etkilemesi nedeniyle, bu işlem dizimizin işlevselliğinin java.util.List
arayüzündeki iletilerle—java.util.RandomAccess
bir gösterge arayüz≝ (İng., marker interface)3 olduğu için bu yönde bir katkı sağlamaz—genişletilmesini sağlar. Ancak, bu arayüzün veri kümesini büyütmeye yönelik iletilerinin, dizinin statik doğası nedeniyle, kullanılamayacağı unutulmamalıdır.List<Integer> tList = Arrays.asList(tekler); // tekler[2]'de 121 değerine sahip olacak. tList.set(2, 121); tList.add(123); // → UnsupportedOperationException
- Kıyım işlemi, doğrudan veya dolaylı bir biçimde dizi gibi rasgele erişimli veri yapılarının kullanıldığı arama algoritmalarında, aranan anahtar değerinin tamsayıya çevrilmesini sağlayarak rasgele erişimli veri yapılarının avantajlarından yararlanmayı olanaklı kılar. ↑
- Aranmakta olan anahtar değerin dizi içinde birden çok geçmesi durumunda, hangi indisin döndürüleceği konusunda garantili bir tahmin yapılması olanaklı değildir. ↑
- İleti içermeyen arayüzlere gösterge arayüz denir. ↑
Hiç yorum yok:
Yorum Gönder
Not: Yalnızca bu blogun üyesi yorum gönderebilir.