C# Koleksiyonlar

Koleksiyon Sınıfları

System.Collections veri saklama için kullanılan sınıflarımızın bulunduğu isim alanıdır. Bu öğrenme faaliyetinde Koleksiyon isim alanı içerisinde yer alan sınıfları inceleyeceğiz.

ArrayList

ArrayList, kısaca sınırları dinamik olarak değişebilen diziler olarak tanımlanır. Dizinin benzeridir fakat sadece object tipinden verileri saklar. Yani içeriğin bir kısmı int türünde, bir kısmı string türünde veya bool türünde olabilir. Belirli bir türde olma zorunluluğu yoktur.

Ayrıca belirli bir sınır vermemize gerek yoktur. Yeni nesne eklendikçe boyutunu otomatikman arttırır. Add, Remove, Sort ve indeksleme metotlarına sahip olması işlem yapmayı kolaylaştırır.

Klasik bir dizide karşılaşabileceğimiz sorunlar genel olarak şu şekildedir;

  • Dizi boyutları sınırlıdır ve sabittir,
  • Dizilerin tüm elemanları aynı türden olmalıdır,
  • Kullanmadığımız dizi elemanlarından dolayı bellek alanları gereksiz yere işgal edilmektedir.

ArrayList ve klasik bir dizinin arasındaki farklılardan bazılarını inceleyelim.

  • 5 elemanlık int türünde sayilar isminde bir dizi tanımlayalım ve bu dizi içerisine 10 adet veri girmeye çalışalım.

[csharp]static void Main(string[] args)
{
int[] sayilar = new int[5];
for (int i = 0; i <= 9; i++)
{
sayilar[i] = i;
}
Console.ReadKey();
}[/csharp]

Yukarıdaki kodları çalıştırdığımız zaman aşağıda görülen dizi sınır değer aşımı (IndexOutOfRangeException) hatasını alırız.

IndexOutOfRangeException hatası

IndexOutOfRangeException hatası

  • Oysa burada klasik bir dizi yerine dinamik bir yapıda bulunan ArrayList kullanmış olsaydık, dizi boyutu ile ilgili bir hata almazdık.

[csharp]static void Main(string[] args)
{
ArrayList sayilar = new ArrayList[5];
for (int i = 0; i <= 9; i++)
{
sayilar.Add(i);
}
Console.ReadKey();
}[/csharp]

  • Şimdi de bir önceki adımda tanımladığımız sayilar dizimizin içerisine string ve bool türünde veriler eklemeye çalışalım.

[csharp]static void Main(string[] args)
{
int[] sayilar=new int[5];
sayilar[0] = “Türkiye”;
sayilar[l] = true;
Console.ReadKey();
}[/csharp]

Yukarıdaki kodları derlemeye çalıştığımız zaman “Türkiye” ve “true” ibarelerin altlarının kırmızı ile çizilmiş olduğunu ve burada bir hata olduğunu görürüz. Aşağıda görünen int türünden string türüne (Cannot implicitly convert type ‘string’ to ‘int’) ve int türünden bool türüne (Cannot implicitly convert type ‘bool’ to ‘int’) dönüştürememe hatalarını alırız.

Tür Dönüşüm Hataları

Tür Dönüşüm Hataları

Aynı atama işlemlerini bir de ArrayList kullanarak yapmayı deneyelim.

[csharp]
static void Main(string[] args)
{
ArrayList sayilar = new ArrayList();
sayilar.Add(“Türkiye”);
sayilar.Add(true);
}[/csharp]

Bu kodların derlenmesi sırasında herhangi bir hata mesajı almaz ve verilerimizi başarılı bir şekilde sayilar isimli ArrayList içerisine aktarırız. Görüldüğü gibi ArrayListlere herhangi bir veri türünde veri ekleyebiliriz.

Queue – Stack

Queue (Kuyruk) ve Stack (Y ığın) da içerisinde birden fazla veri depolayabildiğimiz yapılardandır.
Queue (Kuyruk) sınıfının özelliği ilk giren ilk çıkar (first-in first-out, FIFO) prensibine göre çalışır. Bir eleman arkaya sıradan katılır (enqueue işlemi) ve sırayı önden terk eder(dequeue işlemi).

Queue (Kuyruk) sınıfı

Queue (Kuyruk) Sınıfı

Şekilde görüldüğü gibi Queue (Kuyruk) koleksiyon sınıfında elemanlar koleksiyona arkadan katılırlar ve ilk giren eleman kuyruktan ilk çıkan eleman olur.

[csharp]static void Main(string[] args)
{
Queue ku = new Queue(6);
ku.Enqueue(“Ahmet”);
ku.Enqueue(“Selim”);
ku.Enqueue(“Zeki”);
ku.Enqueue(“Yılmaz”);
ku.Enqueue(123);
ku.Enqueue(false);
Console.WriteLine(“Çıkan eleman {0}, ku.Dequeue().ToString());
Console.WriteLine(“Çıkan eleman {0}, ku.Dequeue().ToString());
Console.WriteLine(“Çıkan eleman {0}, ku.Dequeue().ToString());
Console.WriteLine(“Çıkan eleman {0}, ku.Dequeue().ToString());
Console.WriteLine(“——————“);
IEnumerator dizi = ku.GetEnumerator();
while (dizi.MoveNext())
{
Console-WriteLine(“Güncel eleman {0}”, dizi.Current.ToString());
}
Console.ReadKey(),
}[/csharp]

Yukarıda ku isimli 6 elemanlı Queue (Kuyruk) dizisi tanımlanmış. Elemanları (Ahmet, Selim, Zeki, Yılmaz, 123, false) diziye eklemek için enqueue metodu kullanılmıştır. Dequeue metodu kullanılarak ilk giren (en alttaki) elemanı verirken, aynı zamanda bu elemanı ku dizisinden siler. Ku dizisinin elemanlarını Ienumaratör ara yüzünden bir nesneye (dizi) aktarıyoruz. Current metodu ile dizi nesnesinde yer alan güncel elemanları elde ederiz. Böylelikle ku dizisindeki elemanlar koleksiyona arkadan katılır ve ilk giren eleman kuyruktan ilk çıkan eleman olur. Ekran çıktısı aşağıdaki gibidir.

Ekran Çıktısı:
Çıkan eleman Ahmet
Çıkan eleman Selim
Çıkan eleman Zeki
Çıkan eleman Yılmaz
——————
Güncel eleman 123
Güncel eleman False

Stack (yığın) sınıfının özelliği “son giren ilk çıkar (last-in first-out, LIFO)” prensibine göre çalışmalarıdır. Bir eleman yığına üstten katılır (push işlemi) ve yığını yine üstten terk eder (pop işlemi). Bu yöntemi mutfaktaki kirli tabaklara benzetebiliriz. Her zaman ilk önce en üste konan tabak yıkanır.

Stack (Yığın) sınıfı

Stack (Yığın) Sınıfı

Şekilde görüldüğü gibi stack koleksiyonunda yer alan elemanlardan son girene ulaşmak oldukça kolaydır. Oysaki ilk girdiğimiz elemana ulaşmak için, bu elemanın üstünde yer alan diğer tüm elemanları silmemiz gerekmektedir.

 

[csharp]static void Main(string[] args)
{
Stack stek = new Stack(6);
stek.Push(“ALi”);
stek.Push(“MEHMET”);
stek.Push(“ZEHRA”);
stek.Push(“ZEKi”);
stek.Push(16);
stek.Push(true);
Console.WriteLine(“Çıkan eleman {0}”, stek.Pop().ToString());
Console.WriteLine(“Çıkan eleman {0}”, stek.Pop().ToString());
Console.WriteLine(“Çıkan eleman {0}”, stek.Pop().ToString());
Console.WriteLine(“Çıkan eleman {0}”, stek.Pop().ToString());
Console.WriteLine(“——————“);
IEnumerator dizi = stek.GetEnumerator();
while (dizi.MoveNext())
{
Console.WriteLine(“Güncel eleman {0}”, dizi.Current.ToString());
}
Console.ReadKey();
}[/csharp]

Yukarıda stek isimli 6 elemanlı Stack (Yığın) dizisi tanımlanmış. Elemanları (ALİ, MEHMET, ZEHRA, ZEKİ, 16, True) diziye eklemek için Push methodu kullanılmıştır. Pop methodu kullanılarak son giren (kalan) elemanı verirken, aynı zamanda bu elemanı stek dizisinden siler. Stek dizisinin elemanlarını Ienumaratör arayüzünden bir nesneye (dizi) aktarıyoruz. Current methodu ile dizi nesnesinde yer alan güncel elemanları elde ederiz. Böylelikle stek dizisindeki elemanlara son katılan ilk çıkar, bir eleman yığına üstten katılır ve yığını yine üstten terk eder. Ekran çıktısı aşağıdaki gibidir.

Ekran çıktısı:
Çıkan eleman True
Çıkan eleman 16
Çıkan eleman ZEKİ
Çıkan eleman ZEHRA
——————
Güncel eleman MEHMET
Güncel eleman ALİ

Hashtable

Hashtable (Karışık masa) koleksiyon sınıfında veriler key-value (anahtar-değer) çiftleri şeklinde tutulmaktadırlar. Hashtable koleksiyon sınıflarında key ve value değerleri herhangi bir veri türünde olabilir. Temel olarak bunların hepsi DictionaryEntry (Sözlük Giriş) nesnesidir. Key – value çiftleri hash tablosu adı verilen bir tabloda saklanır.
Key değerleri tektir ve değiştirilemez. Yani bir key-value çiftini koleksiyonumuza eklediğimizde, bu değer çiftinin value değerini değiştirebilirken, key değerini değiştiremeyiz.

Hashtable koleksiyonu verilere hızlı bir şekilde ulaşmamızı sağlayan bir kod yapısına sahiptir. Bu nedenle özellikle arama maliyetlerini düşürdüğü için tercih edilmektedir.

Örnek: Bir konsol uygulaması oluşturarak, Hashtable (Karışık Masa) koleksiyon sınıfı kullanılarak ali, serdar ve utku isminde, yaşları sırasıyla 42, 28 ve 34 olan değerleri tablo şeklinde ekranda sırasıyla yazan program kodu yazılsın.

[csharp]static void Main(string[] args)
{
Hashtable yaslar = new Hashtable();
yaslar[“ali”] = 42;
yaslar[“serdar”] = 28;
yaslar[“utku”] = 34;
foreach (DictionaryEntry element in yaslar)
{
string isim = (string)element.Key;
int yas = (int)element.Value;
Console.WriteLine(“ismi:{0} yaşı:{1}”,isim,yas);
}
Console.ReadKey();
}[/csharp]

Yukarıda yaslar isimli bir hashtable(karışık masa) sınıfı tanımlanarak anahtar (ali, serdar, utku) ve değer (42, 28, 34) çifti tablosu oluşturulmuştur. DictionaryEntry (Sözlük giriş) nesnesi kullanılarak anahtar (key) ve değer (value) dizilerine erişim sağlanmıştır. İsim ve yas isminde anahtar ve değer çifti oluşturarak yaslar sınıfındaki tablo değerleri ekrana yazdırılmıştır. Ekran çıktısı aşağıdaki gibidir.

Ekran çıktısı:
ismi:ali yaşı:42
ismi:utku yaşı:34
ismi:serdar yaşı:28

SortedList

SortedList (Sıralı Liste) sınıfı, hashtable sınıfı ile benzerlik göstermektedir. SortedList sınıfı kullanarak anahtarları, değerlerle ilişkilendirebiliriz. Hashtable’dan farklı olarak anahtarlar dizisinin her zaman sıralanmış olmasıdır.

Bir SortedList sınıfına bir anahtar-değer çifti eklendiğinde anahtar, anahtarlar dizisinin sırasını bozmamak için doğru dizine alfabetik sıraya göre eklenir. Daha sonra değerde, aynı dizinli değerler dizisine eklenir. SortedList sınıfı, bir eleman eklediğinizde ya da bir elemanı kaldırdığınızda, otomatik olarak anahtarlar ve değerleri eş zamanlı hale getirir. Buda anahtar-değer çiftlerini SortedList’e istediğiniz sırada ekleyebileceğiniz anlamına gelir, her zaman anahtarlara göre sıralanır.

Hashtable sınıfında olduğu gibi, bir SortedList aynı anahtardan iki tane içermez. Bir SortedList boyunca yineleme yapmak için bir foreach ifadesi kullanıldığında DictionaryEntry (Sözlük giriş) elde edilir. DictionaryEntry nesneleri key (anahtar) özelliği tarafından sıralanmış olarak döner.

Örnek: Bir konsol uygulaması oluşturarak SortedList (Sıralı Liste) koleksiyon sınıfı kullanılarak semih, metin ve ahmet isminde, yaşları sırasıyla 12, 67 ve 26 olan değerleri tablo şeklinde ekranda alfabetik sırayla yazan program kodu yazılsın.

[csharp]static void Main(string[] args)
{
SortedList yaslar = new SortedList();
yaslar[“semih”] = 12;
yaslar[“metin”] = 67;
yaslar[“ahmet”] = 26;
foreach (DictionaryEntry element in yaslar)
{
string isim = (string)element.Key;
int yas = (int)element.Value;
Console.WriteLine(”ismi:{0} yaşı:{1}”, isim, yas)
}
Console.ReadKey();
}[/csharp]

Yukarıda yaslar isimli bir SortedList (Sıralı Liste) koleksiyon sınıfı tanımlanarak anahtar (semih, metin, ahmet) ve değer (12, 67, 26) çifti tablosu oluşturulmuştur. DictionaryEntry (Sözlükgiriş) nesnesi kullanılarak anahtar (key) ve değer (value) dizilerine erişim sağlanmıştır. İsim ve yas isminde anahtar ve değer çifti oluşturarak yaslar sınıfındaki tablo değerleri, isimler alfabetik sıraya göre ekrana yazdırılmıştır. Ekran çıktısı aşağıdaki gibidir.
Ekran çıktısı:
ismi:ahmet yaşı:26
ismi:metin yaşı:67
ismi:semih yaşı:12

Koleksiyon Başlatıcıları

Koleksiyon sınıflarında yapılan örnekler, bir koleksiyona o koleksiyon için en uygun yöntemi (ArrayList için Add, Stack için Pop gibi) kullanarak tek tek elemanları nasıl ekleyeceğinizi gösterir. Ayrıca diziler tarafından desteklenen sözdizimine (komut) oldukça benzer bir söz dizimi kullanarak, bazı koleksiyon türlerini tanımlarken aynı zamanda başlatabiliriz. Örneğin aşağıdaki ifade, numaralar ArrayList dizisini oluşturur ve başlatır. Sürekli olarak Add yöntemi çağırmamıza gerek kalmaz.

[csharp]ArrayList numaralar = new ArrayList(){10, 3, 4, 6, 9, 13};[/csharp]

Bu sözdizimini (komut satırı) sadece Add yöntemini destekleyen koleksiyonlar için kullanabiliriz (Stack ve Queue sınıfları desteklemez).

Hashtable gibi anahtar – değer çifti alan daha karmaşık koleksiyonlar için, aşağıdaki gibi her anahtar – değer çiftini başlatıcı listesinde anonim tür olarak belirleyebiliriz.

[csharp]Hashtable yas = new HashtableO{{“Serdar”, 24}, {“Ahmet”, 32}, {“Murat”, 27}};[/csharp]

Her çiftteki ilk eleman anahtar, ikincisi ise değerdir.

 

Kaynak: Megep Modülleri

Ahmet Şenlik

Kocaeli Üniversitesinde Bilgisayar Programcılığı okudum DGS ile 2016 yılında Sakarya Üniversitesi Bilgisayar mühendisliğini kazandım. Yazılımla uğraşmayı çok seviyorum bu alanda kendimi daha da geliştirmeyi düşünüyorum. Eğer siz de seviyorsanız bu işi devam edin başlamadıysanız başlayın başaracağınıza inanın. :)

You may also like...

Bir yanıt yazın

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir

Bu site, istenmeyenleri azaltmak için Akismet kullanıyor. Yorum verilerinizin nasıl işlendiği hakkında daha fazla bilgi edinin.