Veri yapıları ile ilgilemeyi, analizler yapmayı ve bu verileri işlemeyi çok seviyorum. Bu yüzden öğrenmeye kafaya koyduğum Java Collections Framework altında List yapısının bir parçası olarak bulunan Linked List (Bağlı Listeler) yapısını sizlere tanıtmak ve öğrenirken aldığım notları paylaşmak istiyorum.
Java Linked List Nedir, Avantajları, Dezavantajları ve Kullanımı gibi başlıklara geçiş yapmadan önce sizlere ufak bir önerim olacak. Eğer bu yapının temelini detaylı bir şekilde öğrenmek istiyorsanız daha önce paylaşmış olduğum “Java Collections Nedir” isimli içeriğime emrecelen.com.tr/java-collections-nedir/ bu adresi takip ederek ulaşabilirsiniz. Böylelikle Linked List kavramını daha rahat bir şekilde aklımızda canlandırabiliriz. 👌🏻💪🏻
Java Linked List Nedir?
Java Linked List, oluşumlarında node (düğüm) ismi verilen bir elemanda verilerini kayıt altına alan ve bu verileri RAM üzerinde tutan özel bir veri saklama yapısıdır. Hafızada verileri tutma şekli olarak dizilere benzese bile aralarında önemli ölçüde performans farkı mevcuttur.
Yapı olarak bir birine bağlı zincir halkaları olarak düşünebiliriz. Zincir halkalarından tek farkı kopan (çıkartılan) halkanın sonucunda zincir yapısı dağılmamaktadır. Yani Linked List (bağlı liste) üzerinde bir eleman silindiğinde node yapılarından birisi kaldırılır ve işlem sonunda kopan bağ tekrar sağlanmak için dizilim oluşturulur.
Java Linked List Kullanımı
Java Linked List Kullanımı, daha önce alışık olduğumuz bir yapıya sahip basit bir tanımlamanın ardından bir çok tanımlama stili ile kullanmamıza imkan sağlar.
Bu tanımlama yapılarının bazılarını maddeler halinde incelemeye başlayalım. 🕵🏻♂️👨🏻🏫
- Yapmamız gereken ilk başta sınıf yapımıza Linked List kavramını tanıtmak için java kütüphanesinden bir tanımlama gerçekleştirerek işlemimize başlıyoruz.
- Bu kullanım seçeneklerinden birisi non-generic veya generic tanımlama ile Linked List yapısının kullanımı olacaktır.
import java.util.LinkedList;
Java kütüphanemizi sınıf yapımıza import ederek tanıttıktan sonra önümüzde bir çok kullanım seçeneği oluşmuş olacak.
Bu bahsetmiş olduğum tanımlamayı aşağıda bulunan kod editörü üzerinden inceleyebilirsiniz.
LinkedList list = new LinkedList(); ///---> Non Generic Linked List Tanımlaması <---\\\ LinkedList <String> listString = new LinkedList<>(); ///---> Generic Linked List Tanımlaması <---\\\
Eğer, Non-Generic ve Generic konuları hakkında henüz bir fikriniz yoksa daha önce paylaşmış olduğum “Java Generic Nedir” adlı rehber içeriğime emrecelen.com.tr/java-generic-nedir/ bu bağlantıyı takip ederek ulaşabilir ve yeni bir bilgi edinebilirsiniz. 🎓💪🏻
Java üzerinde bulunan Linked List sınıfı sayesinde çeşitli metot özelliklerini (ekleme, silme, listeleme) kullanabiliyoruz. Kendinizi hazır hissediyorsanız bu metotları yakında tanıyalım. 👨🏻🏫🔍👀
Java Linked List Metotları
Java Util kütüphanesi içerisinde bulunan LinkedList yapısını projemize başarılı bir şekilde import ettikten sonra aşağıdaki metot yapılarını kullanmaya başlayabiliriz.
- Add (parametre) ve Add (indis numarası, parametre) Tanımlamış olduğumuz Linked List yapımıza iki türde veri eklemesi gerçekleştirebiliriz. Bunlardan ilkinde bir sonraki indise veri eklerken, bir diğerinde belirtilen indis numarasına ekleme işlemi gerçekleştirir.
list.add("Deneme Verisi"); ///---> Bir sonraki indise veri eklemesi sağlayan metot <---\\\ list.add(0,"Emre Çelen"); ///---> Veriyi belirtilen indis üzerinde ekleme işlemi gerçekleştirerek diğer verileri kaydırır.<---\\\
list.addFirst("Başlangıca Veri Ekliyorum"); ///---> Listenin 0. indisine veri eklemesi gerçekleştirir.<---\\\ list.addLast("Sona Veri Ekliyorum"); ///---> Listenin son indisine veri eklemesi gerçekleştirir. <---\\\
list.remove("Deneme Verisi"); ///---> Liste içerisinde parametre olarak aldığı değer bulunduğu takdirde silme işlemini gerçekleştirir <---\\\ list.remove(0); ///---> Liste üzerinde parametre olarak aldığı indis değerini siler <---\\\\
list.removeFirst(); ///---> Listenin başlangıcındaki değeri siler. <---\\\ list.removeLast(); ///---> Listenin sonundaki değeri siler. <----\\\
list.get(0); ///---> Parametre olarak aldığı indis numrasındaki değeri getirir <---\\\ list.getFirst(); ///---> Listenin ilk indisinde bulunan değeri getirir.<---\\\ list.getLast(); ///---> Listenin son indisinde yer alan değeri getirir.<---\\\
list.stream().count(); ///---> Listemizin eleman sayısını döndüren metot tanımlaması <---\\\
Collections kütüphanesi
içerisinde yer alan bu metodumuz liste içerisindeki verileri küçükten büyüğe doğru sıralar.Collections.sort(list); ///---> java.util.Collections kütüphanesini import ederek kullanabiliriz. <---\\\
Bu metot yapılarını daha yakından tanıyabilmek için hepsinin bir arada olacağı basit bir konsol uygulaması yaparak metotlarımızı daha yakından tanıyalım.
- Linked List metotlarını kullanabilmek için öncelikle “Main” sınıfım üzerinde generic bir liste yapısı tanımladım.
- Tanımlamış olduğum liste yapısına çeşitli verilerin tanımlamasını yaparak yukarıda bahsetmiş olduğum metotları kullanmaya başladım.
- Bu metotların etkisini görebilmek için konsol ekranında çeşitli çıktıların oluşmasını sağlayacak yapılar oluşturdum.
- Oluşturmuş olduğum bu yapının kod halini aşağıdaki kısımdan inceleyebilirsiniz.
import java.util.Collections; import java.util.LinkedList; public class Main { public static void main(String[] args) { ///---> Değişken Tanımlanması <---\\\ String ayrac = new String(new char[10]).replace("\0","-"); ///---> Liste Yapımızın Tanımlanması <---\\\ LinkedList <Integer> list = new LinkedList<>(); list.add(327); list.add(846); list.add(121); list.addLast(86); list.addFirst(314); list.add(419); ///---> Metotları Kullanmaya Başlayalım <---\\\ System.out.println(ayrac+"\n< Java Linked List Metotları >\n"+ayrac); System.out.print("-> Oluşturulan LinkedList Elemanları: "); list.forEach(i -> System.out.print("[ "+i+" ]")); ///---> Linked List yapımızın değerlerine ulaşmak için kullandığımız forach yapımız <---\\\ System.out.println("\n"+ayrac); System.out.print("-> Sıralanan Linked List Elemanları (Sort): "); Collections.sort(list); ///---> Listemizi küçükten büyüğe doğru sıralayan metodumuz <---\\\ list.forEach(i -> System.out.print("[ "+i+" ]")); System.out.println("\n"+ayrac); System.out.print("-> Linked List Üzerinde Bulunan Eleman Sayısı (Count): "+list.stream().count()); System.out.println("\n"+ayrac+"\n-> Get (4) Metodunun Sonucu: "+list.get(4)+"\n"+ayrac); list.removeLast(); list.removeFirst(); list.remove(3); System.out.print("-> Elemanlar Silindikten Sonra LinkedList Yapısı: "); list.forEach(i -> System.out.print("[ "+i+" ]")); System.out.println("\n"+ayrac+"\n-> Kalan Eleman Sayısı (Size): "+list.size()); list.clear(); System.out.println(ayrac+"\n-> Clear Metodunun Sonucunda Eleman Sayısı: "+list.size()+"\n"+ayrac); } }
Kod Çıktısı:
Java üzerinde gördüğünüz gibi Linked List yapısını kullanmak oldukça kolay. Daha önce hazırlanmış Linked List metotları sayesinde veri yapılarımıza kolayca müdahale edebiliyoruz. 🧰🧬
Java Linked List Avantajları
Java Linked List Avantajları, içerisinde yer alan veriler ile birlikte hafızayı dinamik bir şekilde kullanmasıdır. Bu sayede hafızadan silinecek bir veri için hafıza üzerinde alan boşaltacak veya yeni eklenecek bir veri için sadece eklenecek veriye yetecek kadar hafıza üzerinde yer kaplayacaktır.
Böylelikle programlarımıza esneklik ve dinamiklik katacaktır.
Java Linked List Dezavantajları
Java Linked List Dezavantajları, ulaşılmak istenilen rastgele bir veriye ulaşmanın maliyeti normal bir dizi sistemine göre daha çok maliyetlidir. Düğüm yapılarının etkisiyle dizilere göre hafızada daha fazla yer kaplar.
Bunun sonucunda dizi yapılarının programımıza yüklediği yükün daha fazlasını Linked List kullanarak sağlamış oluruz.
Ekstra Bilgi
İstersek bu yapıyı diğer programlama dillerinde olduğu gibi kendimiz de oluşturabilir ve programımıza özgün bir hale getirebiliriz. Tabii bu durum şu an için bizim için karmaşık bir hal gibi gözükebilir. Fakat aklımızın bir yerinde bu bilginin bulunması için basit bir örnek uygulama ile kendi Linked List yapımızı oluşturalım.
- Linked List yapıları düğümlerin bir araya gelmesiyle oluştuğundan dolayı öncelikle “ListNode” isminde bir sınıf oluşturdum.
- Oluşturmuş olduğum bu sınıf içerisinde hangi veri tipinde değerler tutmak istiyorsam o veri tipine ait bir değişken tanımlaması gerçekleştirdim. Bu tanımlamış olduğum değişken düğümümün (node) ilk değeri olacak.
- Daha sonra düğümün bir sonraki değerinin alınabilmesi için oluşturmuş olduğum “ListNode” sınıfının tanımlamasını gerçekleştirdim. Böylelikle işlemlerimin temelini oluşturmuş oldum.
- Daha sonra Linked List yapımın sahip olacağı bağların oluşmasını ilk aşamada sağlayacak ve sürekli bir hale getirecek Constructor (Kurucu Metot) yapısının tanımlamasını gerçekleştirdim.
- Temel ilk adımımı oluşturduğuma göre artık Linked List yapılarında kullanacağımız metotların tanımlamasını gerçekleştirebiliriz. Bunun için “ListManager” isminde bir sınıf oluşturdum.
- Oluşturmuş olduğum bu sınıfta düğüm yapılarımın kontrolünü sağlamak için ilk veri ve sonraki veri için iki adet “ListNode” sınıfımın tanımlamasını gerçekleştirdim.
- Tanımlama işlemimden sonra basit bir kaç metot tanımlaması gerçekleştirerek düğümlerime ilgili değerlerin atanmasını sağladım.
- Son işlem olarak oluşturmuş olduğum bu metotları test etmek için “Main” sınıfıma giderek test işlemine başladım.
Bu işlemlerimden sonra “ListNode” isimli sınıf yapım aşağıdaki halini almış oldu.
public class ListNode { int value; ListNode next; public ListNode(){ this.value = -1; this.next = null; } public ListNode(int value){ this.value = value; this.next = null; } }
Böylelikle “ListManager” sınıf yapım da oluşmuş oldu. İlgili sınıf yapımı aşağıdaki kod bloklarını inceleyerek gözlemleyebilirsiniz.
public class ListManager { ListNode value; ListNode next; ListManager(){ value = null; next = null; } ///---> Listemizin Doluluğunu Kontrol Edelim <---\\\ public boolean listValueCheck(){ if(value != null) return true; else return false; } ///---> Listemize Eleman Ekleyelim <---\\\ public void listFirstAdd(int v){ ListNode listNode = new ListNode(v); if(listValueCheck()==true){ listNode.next = value; this.value = listNode; } else{ this.value = listNode; this.next = listNode; } } public void listLastAdd(int v){ ListNode listNode = new ListNode(v); if(listValueCheck()==true){ next.next = listNode; next = listNode; } else{ this.value = listNode; this.next = listNode; } } ///---> Listemizi Ekrana Yazdıralım <---\\\ public void listWrite(){ ListNode listNode = value; while(listNode != null){ System.out.print("[ "+listNode.value +" ] "); listNode = listNode.next; } } }
public class Main { public static void main(String[] args) { ///---> Değişken ve Sınıf Tanımlaması <---\\\ String ayrac = new String(new char[10]).replace("\0","-"); ListManager listManager = new ListManager(); ///---> Veri Ekleme İşlemi <---\\\ listManager.listFirstAdd(120); listManager.listLastAdd(962); listManager.listFirstAdd(632); listManager.listFirstAdd(317); ///---> Ekrana Yazdırma İşlemi <---\\\ System.out.println(ayrac+"\n< Linked List Kullanımı >\n"+ayrac); System.out.print("-> Tanımladığımız Linked List Verileri :"); listManager.listWrite(); listManager.listLastAdd(149); listManager.listFirstAdd(829); System.out.print("\n"+ayrac+"\n-> Yeni Eklenen Veri İle Linked List Yapısı: "); listManager.listWrite(); System.out.println("\n"+ayrac); } }
Kod Çıktısı:
Sonuç olarak başta karmaşık olarak gördüğüm daha sonra benim için eğlenceli bir hal alan Linked List yapısını sizlere tanıtmış oldum. Bu serüvende Java Linked List Nedir, Kullanımı, Metotları ve beraberinde getirdiği Avantajlar, Dezavantajlar hakkında bilgiler verdim.
Eğer bu konuya ek olarak bir kaynak arayışına girerseniz sizlere Oracle tarafından hazırlanan rehber içeriğini öneririm. Bahsettiğim ilgili içeriğe buraya tıklayarak ulaşabilirsiniz.
Unutmayın, aklınıza takılan, zorlandığınız, eksik veya yanlış gördüğünüz ya da konu işleyişi ile alakalı önerilerinizi aşağıda bulunan yorum yap kısmından bana iletebilirsiniz.👍🏻💬👋🏻