Koray Kırdinli

Yazılım ve İş Yaşamı Hakkında Paylaşımlar

MCTS – 4.Collections and Generics

4. Collections and Generics

Collection’lar veriyi saklamak,gruplamak ve içerisinde gezinmek için kullanılırlar.Array’ler de bu işe yarar fakat collection’lar array’lerin geliştirilmiş versiyonudur.

System.Collections namespace’i : Arraylist, Collection interfaces, iterators, Hastable, CollectionBase sınıfı,ReadOnlyCollectionBase sınıfı, DictionaryBase sınıfı, DictionaryEntry sınıfı, Comparer sınıfı, Queue sınıfı, SortedList, BitArray, Stack,

System.Collections.Specialized namespace’i : Specialized String sınıfları, Specialized Dictionary, NameValueCollection sınıfı, CollectionsUtil , BitVector32 structure içerir

System.Collections.Generic namespace’i : Collection.Generic interfaces, Generic Dictionary, Generic Comparer, GenericEquality Comparer, Generic KeyValuePair Structure, Generic List,Generic List.Enumerator structure, Generic Sorted List, Generic Queue, Generic SortedDictionary, Generic LinkedList, Generic Stack içerir.

 

Kendi Sort sınıfınızı yazmak :

Normalde arrayler ve listelerin standart Compare metodu vardır bu metod iki değeri karşılaştırır ve birinci değer büyük ise -1 , ikinci değer büyükse 1 , eşitse 0 döndürür. Biz IComparer interface’ini implemente etmiş kendi sınıfımızı yazıp daha sonra Sort metoduna bu Comparer’ı verirsek artık sort işlemi bizim belirlediğimiz kriterlere göre karşılaştırma yapar. Aşağıdaki örnek Comparer tersten sıralamayı anlatmaya çalışmaktadır.

publicclassDescendingStringComparer : IComparer

{

        CaseInsensitiveComparer _comparer = newCaseInsensitiveComparer();

 

#region IComparer Members

        publicint Compare(object x, object y)

        {

            //Bu kod sayesinde (x,y değil y,x) testen sıralama yapılır.

            return _comparer.Compare(y, x);

        }

#endregion

}

list.Sort(newDescendingStringComparer());
şeklinde bir listeyi sort edersek bu sefer küçükten büyüğe değil büyükten küçüğe sıralama yapacaktır.

 

Sequential Lists:
Queue : Kuyruk FIFO ilk giren ilk çıkar şeklinde çalışır. Bir kuyruğa yeni bir eleman eklemek için
Queue q = newQueue();

q.Enqueue(“a”);

q.Enqueue(“b”); geriye bir değer döndürmez.

 

Kuyruktan bir eleman çıkarmak için ise q.Dequeue(); kullanılır ve ilk eleman listeden çıkarılır yani a çıkarılır ve geriye object olarak çıkardığı eleman döner. Eğer kuyruktan eleman çıkarmadan sıradaki elemanla ilgili işlem yapılmak isterse Peek() metodu kullanılabilir.

if (q.Peek() isString)

   q.Dequeue();

 

Stack: Kuyruğun tam tersi mantıkta çalışır LIFO ilk giren son çıkar mantığıyla çalışır.
Stack’a eleman eklemek için Push çıkarmak için Pop metodu kullanılır.

Stack s = newStack ();

s.Push(“a”);

s.Push(“b”);
object o = s.Pop();
//Pop metodundan çıkarılan eleman döner.

Dictionaries:

Hastable : Key-Value şeklinde veri saklamak için kullanılır. Bir dataya bir anahtar yardımıyla erişmek için Hashtable çok kullanışlıdır ancak eleman sayısı az olan listelerde Hastable yerine ListDictionary kullanmak performans açısından daha etkilidir.Hashtable’a veri eklemek ve listelemek aşağıdaki gibidir.
Hashtable h = newHashtable();

h[“adi”] = “koray”;

h[“mail”] = “koraykirdinli@yahoo.com”;

foreach (DictionaryEntry item in h)

{

    listBox4.Items.Add(item.Key +” : “+ item.Value);

}

 

DictionaryEntry key/value çiftlerini saklamak için kullanılan bir konteyner nesnedir. Bütün Dictionary sınıfları IDictionary interface’ini implement eder. IDictionary interface’inin önemli property ve metodları şunlardır.
IsFixedSize,IsReadOnly,Item,Keys,Values – Add,Clear,Contains,GetEnumarator,Remove.

IDictionary interface’inde IList interface’inden farkı IList nesnelere indexi ile IDictionary nesneleri anahtar değeri ile erişir.

Hashtable listelerde bir key veya Value değerinin var olup olmadığını anlayabilmek için iki metod vardır:ContainsKey,ContainsValue. Hashtable listede aynı keye sahip birden fazla key olamaz.

Eğer Hashtable’a key olarak bir sınıf nesnesi vererek eklersek bu sefer Name’leri aynı olsa bile farklı olarak algılar.

Person p1 = newPerson(“Koray”);

Person p2 = newPerson(“Koray”);

Hashtable h2 = newHashtable();

h2[p1] = “a”;

h2[p2] = “a”;

//Bu sefer Person sınıfının Equals ve GetHashCode metodlarını override ettiğimiz için

//bütün özellikleri aynı olsa da farklı iki eleman olarak alır.
publicclassPerson

{

    publicstring Name;

    public Person(string name)

    {

        Name = name;

    }

    publicoverridebool Equals(object obj)

    {

        Person other = obj asPerson;

        if (other == null) returnfalse;

        return other.Name == Name;

    }

    publicoverrideint GetHashCode()

    {

        return Name.GetHashCode();

    }

}

//———————————————————————————-

 

publicclassInsensitiveComparer : IEqualityComparer

{

    //Bu comparer karşılaştırmayı case-insensitive olarak yapmayı sağlar.

    CaseInsensitiveComparer _comparer = newCaseInsensitiveComparer();

 

    publicint GetHashCode(object obj)

    {

        return obj.ToString().ToLowerInvariant().GetHashCode();

    }

 

    publicnewbool Equals(object x, object y)

    {

        if (_comparer.Compare(x, y) == 0)

        {

            returntrue;

        }

        elsereturnfalse;

    }

}

Hashtable h3 = newHashtable(newInsensitiveComparer());

h3[“aa”] = “a”;

h3[“Aa”] = “a”;

h3[“AA”] = “a”;

Console.WriteLine(h3.Count);// insensitive comparer kullandığımız için 3 değil 1’dir.

 

//———————————————————————————-

 

SortedList:

//SortedListlerde Hashtable’a ek olarak bir elemana hem key ile hem de index ile //erişebiliriz. Elemanı eklediğimiz anda listede uygun yere ekleme yapar.

SortedList list = newSortedList();

list[“First”] = 1;

list[“Second”] = 2;

list[“first”] = “1”;

//Yukardaki listede indexler bu şekilde oluşur. 0:first,1:First,2:Second

 

list.GetByIndex(2);

foreach (DictionaryEntry item in list)

{

    listBox5.Items.Add(item.Key+” : “ +item.Value);

}

 

Özelleştirilmiş Dictionary’ler:

 

Eleman sayısı 10 dan az ise Hastable yerine ListDictionary kullanmak performans açısından daha iyidir.ListDictionary Hastable ile aynı interface’leri implement eder , kullanımı da aynıdır.

 

HybridDictionary: Eğer bir listenin eleman sayısının az veya çok olduğunu önceden kestiremiyorsak HybridDictionary kullanılmalıdır. Interface’leri ve kullanımı yine aynıdır.

 

OrderedDictionary: Keyleri sıralı bir listeye ihtiyacınız olduğunda Hastable işe yaramaz ayrıca bir elemana indexi ile erişmekte mümkün olmaz. SortedList ise keyler beklediğiniz gibi sıralanmıyorsa OrderedDictionary kullanılabilir. Ekstra birkaç özelliği daha vardır.

Özelleştirilmiş tipi olan Koleksiyonlar.

BitArray : true , false tutmak için kullanılır ve elemanları Xor , And gibi bitsel işlemler yapılabilir.
BitVector32 : bitleri 32 bit integer değer olarak saklamaya yarar.
StringCollection : ArrayList gibidir ancak sadece string içerir.

 

 

Bir Hashtable veya SortedList’i case insensitive yapmak için aşağıdaki şekilde yaratabiliriz.
Hashtable ht= CollectionsUtil.CreateCaseInsensitiveHashtable();

SortedList sl = CollectionsUtil.CreateCaseInsensitiveSortedList();

 

Normal şartlarda karşılaştırma işlemi o anki thread’in bölgesel ayarına göre yapılır ancak bunu değiştirmek aşağıdaki kod ile mümkün.

Hashtable ht2 = newHashtable(StringComparer.InvariantCulture);

 

NameValueCollection : key/value alır ancak bir keye ait birden fazla value olabilir.

NameValueCollection list = newNameValueCollection();

list.Add(“key1”, “value1”);

list.Add(“key1”,“value2”);

list.Add(“key2”, “value3”);

foreach (string s in list.GetValues(“key1”))

{

    listBox6.Items.Add(s);

}
//———————————————————————————-

 

GENERIC COLLECTIONS

Generic koleksiyonların daha önce bahsettiğimiz Arralist,HashTable gibi koleksiyonlardan en önemli farkı type-safe yani belli bir tipte olması , boxing unboxing den kurtulmamızı ve dolayısıyla performansımızı artırmamızı sağlar. Böylece run time da istenmeyen hataları da azaltmış oluruz.

publicclassMyList : ICollection, IEnumerable

{

  //Bu sınıf sadece T tipinde değere alan bir koleksiyondur. Kendimiz tip güvenli yapmış olduk. T bu sınıf tanımlanırken integer,string vs olarak tanımlanabilir.

        ArrayList array = newArrayList();

 

        publicvoid Add(T val)

        {

            array.Add(val);

        }

        public T this[int index]

        {

            get { return (T)array[index]; }

        }

#region ICollection Members

#endregion

 

#region IEnumerable Members

#endregion

 }

 

//Bu tanımlama sayesinde bu liste sadece integer değer alabilir hale geldi.Arraylistin sadece integer alan versiyonu aşağıdaki gibidir.

List<int> list = newList<int>();

list.Add(1);

//list.Add(“2”); ERROR

 

 

 

Generic Delegates:

publicdelegateintComparison(T x, T y);

Bunun avantajı örneğin bir listeyi testen yazdıran bir Comparison nesnesi yapmak istiyorsunuz ancak her bir tip için de bunu tek tek yapmak uzun sürecektir. Bunun yerine Comparison delegesi generic olduğundan tek bir metod ile işlem yapılabilir.

 

Generic queue ve stack da aşağıdaki gibi oluşturulur kullanımı generic olmayan versiyonu ile aynıdır.

Queue<string> queue = newQueue<string>();

Stack<int> stack = newStack<int>();

 

 

Generic Dictionary : Hashtable,ListDictionary ve HybridDictionary koleksiyonlarının generic halidir.
Dictionary<int, string> list = newDictionary<int, string>();

list.Add(1, “koray”);

list.Add(2,“kirdinli”);

list[3] = “aaaaaa”;

 

//Diğer bazı generic koleksiyonların tanımlanması aşağıdaki gibidir.
SortedList<string, bool> sl = newSortedList<string, bool>();

May 1, 2010 - Posted by | C# | , , , ,

1 Comment »

  1. I used to be suggested this website through my cousin.
    I’m no longer certain whether or not this put up is written by way of him as no one else realize such detailed about my trouble. You are wonderful! Thank you!

    Comment by Study abroad Students | January 5, 2013 | Reply


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s