İçindekilerGirişİndex
YukarıİlkÖncekiSonrakiSon
Geriİleri
Yazdır
Zafer Teker
tekzaf@yahoo.com

C#.Net ile Nesneleri Sıralama ve IComparable,IComparer Kullanımı

Birden fazla nesnenin sıralabilmesi için nesnelerin karşılaştırılabilir olması gerekir. Örneğin bir sayı diğer sayıdan ya daha büyüktür, ya daha küçüktür yada eşittir. Bu karşılaştırılabilme bilgisi sayesinde bir int dizisi sıralabilir. Aynı karşılaştırma özelliği string içinde geçerlidir. "Ali" her zaman "Zafer" den önce gelir. Alfabetik sıra karşılaştırma kuralını bize verir. Peki yarattığınız herhangi bir class'ın birden fazla nesnesini nasıl sıralarsınız. Örneğin Person adlı bir class'ınız var. Elinizde 5 tane Person nesnesi var. Bu nesneleri nasıl sıralıyabilirsiniz. İşte bu yazının konusu bu.

Nesnelerin Sıralanması

int,string gibi basit tiplerin compareTo(object o) method'ları bulunmaktadır. bu method verilen diğer tip ile nesnenin kendisini karşılaştırması için kullanılır. Örneğin:

int i=4;
int sonuc=i.compareTo(5);

şeklinde kullanılabilir. i sayısı 4 5'ten küçüktür. Dönen sonuç negatif bir sayı olur. Dönen sayıdan iki sayının hangisinin büyük olduğu veya iki sayının eşit olup olmadığı anlaşılır. comporeTo'da şu kural geçerlidir.

Eğer verilen sayı büyükse sonuç:negatif
Eğer verilen sayıs küçükse sonuç:pozitif
İki sayı eşitse sonuc: 0

compareTo methodundan dönen sonuç ile iki sayıyı karşılaştırmış olursunuz.

compareTo en çok sıralama işleminde kullanılır. Örneğin bir dizideki tüm elemanlar birbirleriyle karşılaştırılarak sıralama yapılır. Örneğin bir int dizisi aşağıdaki gibi sıralanabilir.

int[]a=new int[]{4,5,1,5,2,3};
Array.Sort(a);

artık a dizisi küçükten büyüye sıralanmış olacaktır.

Eğer kendi yaptığınız bir class'ın nesnelerini sıralamak istiyorsanız IComparable interface'ni kullanmanız gerekir. IComparable bir interface'dir ve sadece tek bir methodu vardır: compareTo(object o). Yaptığınız class bu interface'si implement edecek ve compareTo methodunu dolduracak. Aşağıda bir Person class'ı bulunmakta. Bu class ad,soyad ve yaş degiskenlerini içermekte. Bir Person dizisi sıralandığında yaşa göre sıralanmasını istiyoruz. Aynı yaşta olanların ada göre, adlarıda aynı olanların soyada göre sıralanmasını istiyoruz.

Person.csİndir Göster Gizle Kopar Satır Gizle Satır Göster
  1 using System;
  2 namespace TestApp
  3 {
  4   public class Person : IComparable
  5   {
  6     private string ad;
  7     private string soyad;
  8     private int yas;
  9     public Person(string ad,string soyad,int yas){
 10       this.ad=ad;
 11       this.soyad=soyad;
 12       this.yas=yas;
 13     }
 14     public string Ad{
 15       get{return ad;}
 16     }
 17     public string Soyad{
 18       get{return soyad;}
 19     }
 20     public int Yas{
 21       get{return yas;}
 22     }
 23     public int CompareTo(object obj)
 24     {
 25       Person p=(Person)obj;
 26       int sonuc=yas.CompareTo(p.Yas);
 27       if(sonuc==0){
 28         sonuc=ad.CompareTo(p.Ad);
 29         if(sonuc==0){
 30           sonuc=soyad.CompareTo(p.Soyad);
 31         }          
 32       }
 33       return sonuc;
 34     }
 35     public override string ToString(){
 36       return Ad+" "+Soyad+" : "+Yas;
 37     }
 38   }
 39 }

Görüldüğü gibi Person class'ı IComparable interface'sini implement etmiş ve compareTo method'nu yazmış. Önce verilen object Person'a cast edilir. Önce yas karşılaştırılır. Eğer yaşlar eşitse sonuç gönderilir. Eğer yaşlar eşitse bu sefer ad kontrol edilir. Eğer adlarda eşitse soyada bakılır. Aşğıdaki basit bir test uygulaması yapılmıştır.

TestApp.csİndir Göster Gizle Kopar Satır Gizle Satır Göster
  1 using System;
  2 namespace TestApp
  3 {
  4   public class TestApp
  5   {
  6     public static void Main(string[] args){
  7       Person[] persons=new Person[5];
  8       persons[0]=new Person("Ali","Yılmaz",10);
  9       persons[1]=new Person("Veli","Yılmaz",13);
 10       persons[2]=new Person("Ali","Kaya",13);
 11       persons[3]=new Person("Mehmet","Kaya",10);
 12       persons[4]=new Person("Mehmet","Yılmaz",11);
 13       Array.Sort(persons);
 14       for(int i=0;i<persons.Length;i++){
 15         Console.WriteLine(persons[i]);
 16       }
 17     }
 18   }
 19 }

Sıralama yapıldıktan sonra aşağıdaki sıraya göre ekrana basılacaktır.:

Ali Yılmaz : 10
Mehmet Kaya : 10
Mehmet Yılmaz : 11
Ali Kaya : 13
Veli Yılmaz : 13

Nesnelerin Birden Fazla Değişik Şekilde Sıralanması

Nesnelerinizi birden fazla değişik şekilde sıralamak isteyebilirsiniz. Örneğin Person'ları adlarına göre sıralamak isteyebilirsiniz. IComparable sadece bir şekilde sıralamanıza izin veriyor. Değişik şekilde sıralama yapmak istiyorsanız IComparer interface'ni kullanmanız gerekir.

Person class'ına bir inner class ekleyelim. Bu class IComporer'i implements etsin.

public class ComparerByName : IComparer{
	public int Compare(object o1,object o2){
		Person p1=(Person)o1;
		Person p2=(Person)o2;
		int sonuc=p1.Ad.CompareTo(p2.Ad);
		if(sonuc==0){
			sonuc=p1.Soyad.CompareTo(p2.Soyad);  
		}
		return sonuc;					
	}
}

Yukarıda görüldüğü gibi karşılaştırma önce ada sonra soyada göre yapılıyor. Şimdi diziyi ada göre sıralamak için Array classının sort methodu aşağıdaki gibi çağrılır:

Array.Sort(persons,new Person.ComparerByName());

sort methodunun IComparer alan bir versiyonuda bulunmaktadır. Böylece persons dizisi ada göre sıralanmış olur.

Dosya Listesi

İçindekilerGirişİndex
YukarıİlkÖncekiSonrakiSon
Geriİleri
Yazdır