MERHABA! Önceki derslerde, dizileri derinlemesine incelemiş ve dizilerle çalışmanın yaygın örneklerini gözden geçirmiştik. Bu derste, Java ArrayList'i daha yakından inceleyeceğiz. Genel olarak, diziler çok kullanışlıdır. Ve zaten fark ettiğiniz gibi, onlarla çok şey yapabilirsiniz :) Ancak dizilerin bazı eksiklikleri vardır.
  • Sınırlı boyut. Oluşturduğunuz anda dizinizin kaç eleman içermesi gerektiğini bilmeniz gerekir. Hafife alırsanız, yeterli alanınız olmaz. Fazla tahmin edin ve dizi yarı boş kalacaktır ki bu da kötüdür. Ne de olsa, hala gereğinden fazla bellek ayırıyorsunuz.

  • Bir dizi, öğe eklemek için yöntemlere sahip değildir. Bir öğe eklemek istediğiniz konumun dizinini her zaman açıkça belirtmelisiniz. Yanlışlıkla ihtiyacınız olan bir değer tarafından işgal edilen bir pozisyon için indeks belirtirseniz, üzerine yazılacaktır.

  • Bir öğeyi silmek için herhangi bir yöntem yoktur. Bir değer yalnızca "sıfırlanabilir".

public class Cat {

   private String name;

   public Cat(String name) {
       this.name = name;
   }

   public static void main(String[] args) {

       Cat[] cats = new Cat[3];
       cats[0] = new Cat("Thomas");
       cats[1] = new Cat("Behemoth");
       cats[2] = new Cat("Lionel Messi");

       cats[1] = null;

      
      
       System.out.println(Arrays.toString(cats));
   }

   @Override
   public String toString() {
       return "Cat{" +
               "name='" + name + '\'' +
               '}';
   }
}
Çıktı: [Cat{name='Thomas'}, null, Cat{name='Lionel Messi'}] Neyse ki, Java'nın yaratıcıları dizilerin avantaj ve dezavantajlarını gayet iyi biliyorlar ve bu nedenle Java ArrayList adında çok ilginç bir veri yapısı yarattılar . Mümkün olduğu kadar basit bir şekilde ifade etmek gerekirse, bir Java ArrayList pek çok yeni özelliğe sahip "güçlendirilmiş" bir dizidir.

ArrayList Nasıl Oluşturulur

Oluşturmak çok kolaydır:

ArrayList<Cat> cats = new ArrayList<Cat>();
Şimdi, Cat nesnelerini depolamak için bir liste oluşturduk . Otomatik olarak genişleyebildiği için ArrayList boyutunu belirtmediğimize dikkat edin . Bu nasıl mümkün olabilir? Aslında oldukça basit. Sizi şaşırtabilir ama Java'daki ArrayList çok sıradan bir dizinin üzerine inşa edilmiştir :) Evet, bir dizi içerir ve elemanlarımız burada depolanır. Ancak Java'daki ArrayList'in bu diziyle özel bir çalışma yöntemi vardır:
  • Dahili dizi dolduğunda, ArrayList dahili olarak yeni bir dizi oluşturur. Yeni dizinin boyutu, eski dizinin boyutu çarpı 1,5 artı 1'dir.

  • Tüm veriler eski diziden yeni diziye kopyalanır.

  • Eski dizi, çöp toplayıcı tarafından temizlenir.
Bu mekanizma, Java ArrayList'in (sıradan bir diziden farklı olarak) yeni öğeler eklemek için bir yöntem uygulamasına izin verir. bu add()yöntem

public static void main(String[] args) {

   ArrayList<Cat> cats = new ArrayList<Cat>();
   cats.add(new Cat("Behemoth"));
}
Listenin sonuna yeni öğeler eklenir. Artık diziden taşma riski yoktur, bu nedenle bu yöntem tamamen güvenlidir. Bu arada, ArrayList bir nesneyi yalnızca dizinine göre bulmakla kalmaz, bunun tersi de geçerlidir: ArrayList'te bir nesnenin dizinini bulmak için bir başvuru kullanabilir ! indexOf() yöntemi bunun içindir : İstediğimiz nesneye bir başvuru iletiriz ve indexOf() onun dizinini döndürür:

public static void main(String[] args) {

   ArrayList<Cat> cats = new ArrayList<>();
   Cat thomas = new Cat("Thomas");
   Cat behemoth = new Cat("Behemoth");
   Cat lionel = new Cat("Lionel Messi");
   Cat fluffy = new Cat ("Fluffy");

   cats.add(thomas);
   cats.add(behemoth);
   cats.add(lionel);
   cats.add(fluffy);

   int thomasIndex = cats.indexOf(thomas);
   System.out.println(thomasIndex);
}
Çıktı: 0 Bu doğru. Thomas nesnemiz gerçekten de 0 öğesinde depolanmıştır. Dizilerin yalnızca dezavantajları yoktur. Ayrıca tartışılmaz avantajları da var. Bunlardan biri, öğeleri dizine göre arama yeteneğidir. Bir dizine, yani belirli bir bellek adresine işaret ettiğimiz için, bu şekilde bir dizi aramak çok hızlıdır. ArrayListnasıl yapılacağını da biliyor! get () yöntemi bunu uygular:

public static void main(String[] args) {

   ArrayList<Cat> cats = new ArrayList<>();
   Cat thomas = new Cat("Thomas");
   Cat behemoth = new Cat("Behemoth");
   Cat lionel = new Cat("Lionel Messi");
   Cat fluffy = new Cat ("Fluffy");

   cats.add(thomas);
   cats.add(behemoth);
   cats.add(lionel);
   cats.add(fluffy);

   Cat secondCat = cats.get(1);

   System.out.println(secondCat);
}
Çıktı: Cat{name='Behemoth'} Ayrıca, ArrayList'in belirli bir nesne içerip içermediğini kolayca öğrenebilirsiniz. Bu, ArrayList include() yöntemi kullanılarak yapılır :

public static void main(String[] args) {

   ArrayList<Cat> cats = new ArrayList<>();
   Cat thomas = new Cat("Thomas");
   Cat behemoth = new Cat("Behemoth");
   Cat lionel = new Cat("Lionel Messi");
   Cat fluffy = new Cat ("Fluffy");

   cats.add(thomas);
   cats.add(behemoth);
   cats.add(lionel);
   cats.add(fluffy);

   cats.remove(fluffy);
   System.out.println(cats.contains(fluffy));
}
Yöntem, ArrayList 'ın dahili dizisinin öğeyi içerip içermediğini kontrol eder ve bir boole (doğru veya yanlış) döndürür. Çıktı: yanlış Ve eklemeyle ilgili başka bir önemli şey. ArrayList, öğeleri yalnızca dizinin sonuna değil, herhangi bir yere eklemek için bir dizin kullanmanıza olanak tanır. Bunun için iki yöntemi vardır:
  • ArrayList add(int dizini, Cat öğesi)
  • ArrayList seti(int dizini, Cat öğesi)
Argüman olarak, bu yöntemlerin her ikisi de eklemek istediğiniz konumun dizinini ve nesnenin kendisine bir başvuru alır. Aradaki fark, set() kullanarak eklemenin eski değerin üzerine yazmasıdır. add() kullanarak ekleme, önce [index]'ten tüm öğeleri birer birer dizinin sonuna kaydırır ve ardından belirtilen nesneyi ortaya çıkan boş konuma ekler.

İşte bir örnek:


public static void main(String[] args) {

   ArrayList<Cat> cats = new ArrayList<>();
   Cat thomas = new Cat("Thomas");
   Cat behemoth = new Cat("Behemoth");
   Cat lionel = new Cat("Lionel Messi");
   Cat fluffy = new Cat ("Fluffy");

   cats.add(thomas);
   cats.add(behemoth);

   System.out.println(cats.toString());

   cats.set(0, lionel);// Now we have a list of 2 cats. Adding a 3rd using set

   System.out.println(cats.toString());
}
Çıktı: [[Cat{name='Thomas'}, Cat{name='Behemoth'}] [Cat{name='Lionel Messi'}, Cat{name='Behemoth'}] 2 kedilik bir listemiz vardı . Sonra set() yöntemini kullanarak 0 elemanı olarak bir tane daha ekledik . Sonuç olarak, eski eleman yenisiyle değiştirildi.

public static void main(String[] args) {

   ArrayList<Cat> cats = new ArrayList<>();
   Cat thomas = new Cat("Thomas");
   Cat behemoth = new Cat("Behemoth");
   Cat lionel = new Cat("Lionel Messi");
   Cat fluffy = new Cat ("Fluffy");

   cats.add(thomas);
   cats.add(behemoth);

   System.out.println(cats.toString());

   cats.add(0, lionel);// Now we have a list of 2 cats. Adding a 3rd using add

   System.out.println(cats.toString());
}
Ve burada add() işlevinin farklı çalıştığını görüyoruz . Tüm öğeleri sağa taşır ve ardından yeni değeri öğe 0 olarak yazar. Çıktı: [Cat{name='Thomas'}, Cat{name='Behemoth'}] [Cat{name='Lionel Messi'}, Cat{name='Thomas'}, Cat{name='Behemoth'}] Listeyi tamamen temizlemek için clear() yöntemini kullanıyoruz:

public static void main(String[] args) {

   ArrayList<Cat> cats = new ArrayList<>();
   Cat thomas = new Cat("Thomas");
   Cat behemoth = new Cat("Behemoth");
   Cat lionel = new Cat("Lionel Messi");
   Cat fluffy = new Cat ("Fluffy");

   cats.add(thomas);
   cats.add(behemoth);
   cats.add(lionel);
   cats.add(fluffy);

   cats.clear();

   System.out.println(cats.toString());
}
Çıktı: [] Listeden her şey kaldırıldı. Bu arada, lütfen unutmayın: dizilerin aksine, ArrayList toString() yöntemini geçersiz kılar ve listeyi zaten uygun şekilde dizeler olarak görüntüler. Sıradan dizilerde bunun için Arrays sınıfını kullanmamız gerekiyordu . Ve Arrays'den bahsettiğim için : Java, bir dizi ile bir ArrayList arasında kolayca "geçiş yapmanızı" , yani birini diğerine dönüştürmenizi sağlar . Arrays sınıfı bunun için bir Arrays.asList() yöntemine sahiptir . İçeriği bir dizi olarak almak ve bunları ArrayList yapıcımıza iletmek için kullanırız :

public static void main(String[] args) {

   ArrayList<Cat> cats = new ArrayList<>();


   Cat thomas = new Cat("Thomas");
   Cat behemoth = new Cat("Behemoth");
   Cat lionel = new Cat("Lionel Messi");
   Cat fluffy = new Cat ("Fluffy");

   Cat[] catsArray = {thomas, behemoth, lionel, fluffy};

   ArrayList<Cat> catsList = new ArrayList<>(Arrays.asList(catsArray));
   System.out.println(catsList);
}
Çıktı: [Cat{name='Thomas'}, Cat{name='Behemoth'}, Cat{name='Lionel Messi'}, Cat{name='Fluffy'}] Ayrıca ters yöne de gidebilirsiniz: get ArrayList nesnesinden bir dizi . Bunu toArray() yöntemini kullanarak yaparız :

public static void main(String[] args) {

   ArrayList<Cat> cats = new ArrayList<>();

   Cat thomas = new Cat("Thomas");
   Cat behemoth = new Cat("Behemoth");
   Cat lionel = new Cat("Lionel Messi");
   Cat fluffy = new Cat ("Fluffy");

   cats.add(thomas);
   cats.add(behemoth);
   cats.add(lionel);
   cats.add(fluffy);

   Cat[] catsArray = cats.toArray(new Cat[0]);

   System.out.println(Arrays.toString(catsArray));
}
Not: toArray() yöntemine boş bir dizi geçirdik . Bu bir hata değil. ArrayList sınıfının içinde , bu yöntem, boş bir diziyi geçirme performansını artıracak şekilde uygulanır. Bunu gelecek için aklınızda bulundurun (tabii ki, belirli bir boyutta bir diziyi iletebilirsiniz; bu da işe yarayacaktır). Oh, boyutu hakkında. Listenin mevcut boyutu size () yöntemi kullanılarak bulunabilir:

public static void main(String[] args) {

   ArrayList<Cat> cats = new ArrayList<>();


   Cat thomas = new Cat("Thomas");
   Cat behemoth = new Cat("Behemoth");
   Cat lionel = new Cat("Lionel Messi");
   Cat fluffy = new Cat ("Fluffy");

   cats.add(thomas);
   cats.add(behemoth);
   cats.add(lionel);
   cats.add(fluffy);

   System.out.println(cats.size());
}
Bir dizinin uzunluk özelliğinden farklı olarak, ArrayList.size() yönteminin orijinal kapasiteyi değil gerçek öğe sayısını döndürdüğünü anlamak önemlidir . Sonuçta, ArrayList'i oluştururken bir boyut belirtmedik . Ancak bunu belirtebilirsiniz — ArrayList'in uygun bir oluşturucusu vardır. Ancak yeni öğeler ekleme açısından bu, davranışını değiştirmez:

public static void main(String[] args) {

   ArrayList<Cat> cats = new ArrayList<>(2);// create an ArrayList with an initial capacity of 2


   Cat thomas = new Cat("Thomas");
   Cat behemoth = new Cat("Behemoth");
   Cat lionel = new Cat("Lionel Messi");
   Cat fluffy = new Cat ("Fluffy");

   cats.add(thomas);
   cats.add(behemoth);
   cats.add(lionel);
   cats.add(fluffy);

   System.out.println(cats.size());
}
Konsol çıktısı: 4 2 öğelik bir liste oluşturduk, ancak ihtiyaç duyduğumuzda sessizce genişledi. Başka bir husus da, başlangıçta çok küçük bir liste oluşturursak, daha sık genişletilmesi gerekeceği ve bu da bazı kaynakları kullanacağıdır. Bu derste bir ArrayList'ten öğe çıkarma işlemine pek değinmedik . Elbette bunun nedeni aklımızdan çıkmamış olması değil. Bu konuyu daha sonra görüşeceğiniz ayrı bir derse koyduk :) Öğrendiklerinizi pekiştirmek için Java Kursumuzdan bir video dersi izlemenizi öneririz.