Interface Comparator java.util Interface Comparator Kılgılayan sınıf: Collator Bildirimi: public interface Comparator Comparator arayüzü Java Collections Framework’un bir üyesidir. Bir nesneler koleksiyonu üzerinde tümel sıralama (total ordering) yapar. Bunu yaparken Collections.sort() metodunu kullanabilir. Bu metot, collections içindeki sınıflara ait nesnelerden oluşan koleksiyonları doğal sıraya koyar. Doğal sıralama, örneğin sayılar için küçüklükbüyüklük sırasıdır. Stringler için sözlük sıralamasıdır (lexigeographic order). Ayrıca, TreeSet ya da TreeMap gibi veri yapılarında da doğal sıralama yapar. Ele alınan nesneler koleksiyonu için bir doğal sıralama yoksa ya da doğal sıralamadan farklı bir sıralama yapılmak isteniyorsa, Collections.sort() metodu kullanılamaz. O durumda, arayüzde olan compare(Object o1, Object o2) metodu kullanılır. Tabii, bu metot bir üst sınıfta tanımlanmamışsa, ele alınan sınıfta tanımlanması gerekir. Bir S kümesi üzerinde Comparator c nin koyduğu sıranın eşitlik ile tutarlı olması (be consistent with equals) demek, S kümesi içindeki her e1 ve e2 için (compare((Object)e1, (Object)e2)==0) e1.equals((Object)e2) deyimlerinin aynı boolean değerlerine sahip olması demektir; yani her ikisi aynı zamanda false ya da her ikisi aynı zamanda true değer almalıdır. Eşitlik ile tutarlı olmayan bir sıralama yapan comparator ile oluşturulan bir SortedSet ya da SortedMap yapıları beklenmedik davranışlar gösterebilirler. O nedenle, serileşebilen yapılar kurmak için java.io.Serializable kullanılmalıdır. Đlgili konular: Comparable, Arrays.sort(Object[], Comparator), TreeMap, TreeSet, SortedMap, SortedSet, Serializable Comparator Arayüzünün Metotları int compare(Object o1, Object o2) Đki öğeyi mukayese eder. boolean equals(Object obj) Verilen nesnenin belirtilen nesneye eşit olup olmadığını belirler. 1 java.util.Comparator Örnek: Aşağıdaki program Float tipi nesneleri sort() metodu ile doğal sıraya diziyor. import java.util.*; public class ComparatorDemo implements Comparable { public static void main(String[] args) { List list = new ArrayList(); list.add(new Float(34.3)); list.add(new Float(13.7)); list.add(new Float(25.8)); list.add(new Float(66.0)); Collections.sort(list); System.out.println("Doğal Sıralama:"); System.out.println("Sıralama : " + list); } } /* Doğal Sıralama: Sıralama : [13.7, 25.8, 34.3, 66.0] */ • public class ComparatorDemo { public static void main(String[] args) { /* * Đlkel (primitive) double sayıları mukayese etmek için * compare(double d1, double d2) static metodunu kullanırız. * d1 < d2 ise negatif, d1 = d2 ise 0 , * d1 > d2 ise pozitif değer alır. */ double d1 = 5.35; double d2 = 5.34; int i1 = Double.compare(d1, d2); System.out.println(Double.compare(d1, d2)); System.out.println(Double.compare(d2, d1)); /* * Nesne (object) olarak Double sayıları mukayese * etmek için * int D1.compareTo(Double D2) metodunu kullanırız. * D1 < D2 ise negatif, D1 = D2 ise 0 , * D1 > D2 ise pozitif değer alır. */ Double dObj1 = new Double("5.35"); Double dObj2 = new Double("5.34"); int i2 = dObj1.compareTo(dObj2); System.out.println(dObj1.compareTo(dObj2)); System.out.println(dObj2.compareTo(dObj1)); } 2 } /* 1 -1 1 -1 */ Örnek: Aşağıdaki program Double tipi nesneleri sort() metodu ile doğal sıraya diziyor. import java.util.*; public class ComparatorDemo implements Comparable { public static void main(String[] args) { List list = new ArrayList(); list.add(new Double(34.3)); list.add(new Double(13.7)); list.add(new Double(25.8)); list.add(new Double(66.0)); Collections.sort(list); System.out.println("Doğal Sıralama:"); System.out.println("Sıralama : " + list); } } /* Doğal Sıralama: Sıralama : [13.7, 25.8, 34.3, 66.0] */ int compare(Object o1, Object o2) Metodu Comparator<T> arayüzüne ait olan bu metot, nesneleri mukayese eder. Nesneler arasında mukayese olgusu gerçekleşince, Collections.sort(koleksiyon, sıralama) metodu ile sıralanabilirler. Bunun için aşağıdaki amaçlara uygun Comparator nesnesi yaratılır. Çoklu Mukayese: Bir sınıfa ait nesneler içindeki veri alanlarına göre, nesneleri sıralamak mümkündür. Örnein bir personel sınıfına ait nesneler, soyad, yaş, sicilNo gibi değişkenlere göre sıraya konulabilirler. Sistem Sınıfları: Bazı sınıflara ait doğal sıralamadan farklı sıralama işlemleri yapılabilir. Örneğin, String tipi nesnelerin doğal sırası sözlük sıralamasıdır. Ancak, onları, örneğin, uzunluklarına göre sıralamak isteyebiliriz. Eğer ele alınan sınıfın nesneleri arasında doğal bir sıralama varsa, çoğunlukla onu kullanırız, dolayısıyla bir compare(,) metodu tanımlamaya gerek duymayız. Ama doğal sıralama yok ya da farklı bir sıralama istiyorsak, compare(,) metodunu tanımlarız. Tabii, bu metot Object sınıfına aittir ve 3 mukayeseyi == operatörü gibi yapar. O nedenle, kendi sınıfımızda compare(.) metodu tanımlanınca Object sınıfındaki override edilmiş olur. Örnek: Aşağıdaki program Integer tipinden bir ArrayList yaratıyor ve onu Collections.sort() metodu ile sıralıyor. Bu işlemde programcı bir comparator tanımlamıyor. Ancak Integer sınıfı Comparable arayüzünü kılgılar. Bu arayüz kendisini kılgılayan her sınıfta tümel sıralama (total ordering) yaratır. Bu sıralamaya sınıfın doğal sıralaması (natural ordering) denilir. Arayüzü kılgılayan her sınıfta compareTo(Object o) metodu ilgili sınıfın öğelerini ikişer ikişer birbirleriyle karşılaştırır. Buna doğal mukayese metodu denilir. Comparable arayüzünü kılgılayan listeler, Collections.sort metodu ile arrayler ise Arrays.sort metodu ile otomatik olarak sıraya konulur. Dolayısyla, Comparable arayüzünü kılgılayan nesneler SortedMap yapısında anahtar olarak, SortedSet yapısında ise öğeler olarak kullanılabilirler. Bunu yaparken bir comparator tanımlamaya gerek yoktur. x.compareTo(y) deyimi x ile y nesnelerini mukayese eder. x < y ise ifade – 1 değerini, x = y ise 0 değerini ve x > y ise 1 değerini alır. package comparator; import java.util.ArrayList; import java.util.Collections; import java.util.List; public class ComparatorDemo01 { public static void main(String[] args) { List<Integer> list = new ArrayList<Integer>(); list.add(5); list.add(4); list.add(3); list.add(7); list.add(2); list.add(1); Collections.sort(list); for (Integer k : list) { System.out.print("\t" + k); } } } /* 1 2 3 4 5 7 */ Örnek: Koleksiyonda bir doğal sıralama yoksa ya da koleksiyon doğal sırasından başka türlü sıralanmak istenirse, istenen sıralamayı yapan bir metot tanımlanabilir. Tabii, bunu yapmak için, Comparator 4 arayüzünü kılgılayan bir sınıf tanımlamak gerekir. Aşağıdaki program kendi sıralama metodunu tanımlamaktadır. (Sıralamayı tersine çeviriyor.) //package comparator import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Comparator; public class ComparatorDemo implements Comparator<Integer> { //Bu metot sıralamayı tesine çeviriyor. public int compare(Integer obj1, Integer obj2) { return (obj1 > obj2 ? -1 : (obj1 == obj2 ? 0 : 1)); } } class Uygulama { public static void main(String[] args) { List<Integer> list = new ArrayList<Integer>(); list.add(5); list.add(4); list.add(3); list.add(7); list.add(2); list.add(1); Collections.sort(list, new ComparatorDemo()); for (Integer k : list) { System.out.print("\t" + k); } } } /* 7 5 4 3 2 1 */ Örnek: Koleksiyonda bir doğal sıralama (küçükten büyüğe doğru) varken, sıralamayı tersine çevirmek (büyükten küçüğe doğru) için java Collections sınıfının reverseOrder() metodu kullanılabilir. Aşağıdaki program Comparator yardımıyla bir ArrayList ’i azalan sıraya koymak için sözü edilen metodu kullanmaktadır. import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; public class ComparatorDemo03 { public static void main(String[] args) { // Bir ArrayList yaratıyor 5 ArrayList arrayList = new ArrayList(); // Add elements to Arraylist arrayList.add("A"); arrayList.add("B"); arrayList.add("C"); arrayList.add("D"); arrayList.add("E"); /* * Koleksiyon üzerinde ters sıralamayı oluşturacak comparator * tanımlanıyor */ Comparator comparator = Collections.reverseOrder(); System.out.println("Sıralamadan önceki ArrayList : " + arrayList); /* * Comparatoru kullanarak ArrayList'i oluşturmak için * static void sort(List list, Comparator c) * metodu kullanılıyor. */ Collections.sort(arrayList, comparator); System.out.println("Sıralamadan sonraki ArrayList :" + arrayList); } } /* Sıralamadan önceki ArrayList Sıralamadan sonraki ArrayList */ : [A, B, C, D, E] : [E, D, C, B, A] Örnek: Aşağıdaki program, nesnelerden oluşan bir arrayi, nesnelerin farklı veri alanlarına (yaş ve ad) göre sıralayan metotlar tanımlamakta ve onlara göre sıralama yapmaktadır. java.util.Comparator arayüzünün iki metodu şunlardır: 1) public int compare(Object object1, Object object2) ve 2) boolean equals(Object object) import java.util.*; class Personel { private int age; private String name; public void setAge(int age) { this.age = age; } 6 public int getAge() { return this.age; } public void setName(String name) { this.name = name; } public String getName() { return this.name; } } class AgeComparator implements Comparator { public int compare(Object prs1, Object prs2) { int prs1Age = ((Personel) prs1).getAge(); int prs2Age = ((Personel) prs2).getAge(); if (prs1Age > prs2Age) return 1; else if (prs1Age < prs2Age) return -1; else return 0; } } class NameComparator implements Comparator { public int compare(Object prs1, Object prs2) { /* * parametreler Object tipinden olduğu için onu Personel * sınıfına dönüştürüyoruz (cast) */ String prs1Ad = ((Personel) prs1).getName(); String prs2Ad = ((Personel) prs2).getName(); /* * Personelin adlarını mukayese etmek için * compareTo() metodu kullanılıyor. */ return prs1Ad.compareTo(prs2Ad); } } public class ComparatorDemo04 { public static void main(String args[]) { // Personel array which will hold employees Personel employee[] = new Personel[3]; // Đki personel için veri gir. employee[0] = new Personel(); employee[0].setAge(40); 7 employee[0].setName("Zeynep"); employee[1] = new Personel(); employee[1].setAge(20); employee[1].setName("Burhan"); employee[2] = new Personel(); employee[2].setAge(30); employee[2].setName("Çiğdem"); System.out.println("Sıralamadan önce : "); // print array as is. for (int i = 0; i < employee.length; i++) { System.out.println("Personel " + (i + 1) + " name :: " + employee[i].getName() + ", Age :: " + employee[i].getAge()); } Arrays.sort(employee, new AgeComparator()); System.out.println("\n\n Personeli yaşalarına göre sıraladıktan sonra : "); for (int i = 0; i < employee.length; i++) { System.out.println("Personel " + (i + 1) + " name :: " + employee[i].getName() + ", Age :: " + employee[i].getAge()); } Arrays.sort(employee, new NameComparator()); System.out.println("\n\n Personeli adlarına göre sıraladıktan sonra :"); for (int i = 0; i < employee.length; i++) { System.out.println("Personel " + (i + 1) + " name :: " + employee[i].getName() + ", Age :: " + employee[i].getAge()); } } } /* Sıralamadan önce : Personel 1 name :: Zeynep, Personel 2 name :: Burhan, Personel 3 name :: Çiğdem, Personeli Personel 1 Personel 2 Personel 3 Personeli Personel 1 Personel 2 Personel 3 */ Age :: 40 Age :: 20 Age :: 30 yaşalarına göre sıraladıktan sonra : name :: Burhan, Age :: 20 name :: Çiğdem, Age :: 30 name :: Zeynep, Age :: 40 adlarına göre sıraladıktan sonra : name :: Burhan, Age :: 20 name :: Zeynep, Age :: 40 name :: Çiğdem, Age :: 30 Örnek: 8 Doğal sıralama için Comparable arayüzünü kılgılamak yeterlidir. Doğal sıralamadan farklı bir sıralama isteniyorsa Comparator arayüzündeki compare(Object1 o1, Object2, o2) metodu kullanılarak istenen sıralama tanımlanabilir. Sıralama tanımlandıktan sonra Collections.sort() metodu ile liste istenen sıraya konulabilir. import java.util.*; public class ComparatorDemo implements Comparable { String ad; int yaş; long gelir; public ComparatorDemo(String ad, int yaş) { this.ad = ad; this.yaş = yaş; } public ComparatorDemo(String ad, int yaş, long gelir) { this.ad = ad; this.yaş = yaş; this.gelir = gelir; } public String getAd() { return ad; } public int getYaş() { return yaş; } public String toString() { return ad + " : " + yaş; } /* * * Bu sınıf için doğal sıralama */ public int compareTo(Object o) { return getAd().compareTo(((ComparatorDemo) o).getAd()); } static class YaşaGöreSırala implements Comparator { /* * java.util.Comparator#compare(java.lang.Object, java.lang.Object) */ public int compare(Object obj1, Object obj2) { ComparatorDemo p1 = (ComparatorDemo) obj1; ComparatorDemo p2 = (ComparatorDemo) obj2; if (p1.getGelir() == 0 && p2.getGelir() == 0) return p1.getYaş() - p2.getYaş(); else return (int) (p1.getGelir() - p2.getGelir()); } } public static void main(String[] args) { List emekli = new ArrayList(); emekli.add(new ComparatorDemo("Kemal", 34)); 9 emekli.add(new ComparatorDemo("Tolga", 13)); emekli.add(new ComparatorDemo("Maviş", 25)); emekli.add(new ComparatorDemo("Derya", 66)); Collections.sort(emekli); System.out.println("Doğal Sıralama:"); System.out.println("Sıralama : " + emekli); Collections.sort(emekli, Collections.reverseOrder()); System.out.println("Doğal Sıralamanın tersi:"); System.out.println("Sıralama : " + emekli); List emekliGeliri = new ArrayList(); emekliGeliri.add(new ComparatorDemo("Kemal", emekliGeliri.add(new ComparatorDemo("Tolga", emekliGeliri.add(new ComparatorDemo("Maviş", emekliGeliri.add(new ComparatorDemo("Derya", 4, 33)); 3, 3)); 25, 666)); 66, 2)); Collections.sort(emekli, new YaşaGöreSırala()); System.out.println("Yaşa göre sırala"); System.out.println("Sıralama : " + emekli); Collections.sort(emekliGeliri, new YaşaGöreSırala()); System.out.println("Yaşa ve gelire göre sırala"); System.out.println("Sıralama : " + emekliGeliri); } public long getGelir() { return gelir; } public void setGelir(long gelir) { this.gelir = gelir; } public void setYaş(int yaş) { this.yaş = yaş; } public void setAd(String ad) { this.ad = ad; } } /* Doğal Sıralama: Sıralama : [Derya : 66, Kemal Doğal Sıralamanın tersi: Sıralama : [Tolga : 13, Maviş Yaşa göre sırala Sıralama : [Tolga : 13, Maviş Yaşa ve gelire göre sırala Sıralama : [Derya : 66, Tolga */ : 34, Maviş : 25, Tolga : 13] : 25, Kemal : 34, Derya : 66] : 25, Kemal : 34, Derya : 66] : 3, Kemal : 4, Maviş : 25] 10