Comparator Arayüzü
Coddy'nin Java Journey'sinin Nesne Yönelimli Programlama bölümünün bir parçası — ders 45 / 87.
Comparable bir sınıfın doğal sıralamasını tanımlarken, bazen nesneleri farklı şekillerde sıralamanız gerekebilir. Comparator arayüzü, orijinal sınıfı değiştirmeden ayrı bir karşılaştırma mantığı oluşturmanıza olanak tanır.
Bir Comparator, aynı türdeki iki nesneyi karşılaştıran harici bir nesnedir. Bu, birden fazla sıralama seçeneği istediğinizde veya sınıfın kendisini değiştiremediğinizde kullanışlıdır:
import java.util.Comparator;
class NameComparator implements Comparator<Person> {
@Override
public int compare(Person p1, Person p2) {
return p1.getName().compareTo(p2.getName());
}
}
class AgeComparator implements Comparator<Person> {
@Override
public int compare(Person p1, Person p2) {
return p1.getAge() - p2.getAge();
}
}Ardından karşılaştırıcıyı sıralama yöntemlerine aktarabilirsiniz:
List<Person> people = new ArrayList<>();
people.add(new Person("Charlie", 30));
people.add(new Person("Alice", 25));
Collections.sort(people, new NameComparator()); // İsme göre sıralandı
Collections.sort(people, new AgeComparator()); // Yaşa göre sıralandıDaha sade bir kod yazmak için, Comparator bir fonksiyonel arayüz olduğundan lambda ifadelerini kullanabilirsiniz:
Collections.sort(people, (p1, p2) -> p1.getName().compareTo(p2.getName()));Temel fark: Comparable, karşılaştırılan sınıf tarafından uygulanır ve tek bir doğal sıralama tanımlar; Comparator ise sınırsız sayıda özel sıralama tanımlayabilen ayrı bir sınıftır.
Görev
KolayComparator arayüzünün gücünü gösteren bir çalışan sıralama sistemi oluşturalım. Employee sınıfının kendisini değiştirmeden, çalışanları farklı şekillerde (maaşa ve isme göre) sıralamak için birden fazla comparator oluşturacaksınız.
Kodunuzu dört dosya halinde düzenleyeceksiniz:
Employee.java: Üç özel (private) alana sahip bir çalışanı temsil eden bir sınıf oluşturun:name(String),department(String) vesalary(double). Tüm alanları başlatan bir yapıcı (constructor) ve her biri için getter metotları ekleyin.toString()metodunu şu formatı döndürecek şekilde geçersiz kılın (override):[name] ([department]) - $[salary]SalaryComparator.java: Çalışanları maaşlarına göre azalan düzende (en yüksek maaşlı ilk sırada) sıralayan bir comparator oluşturun.Comparator<Employee>arayüzünü ve onuncompare()metodunu uygulayın. Maaş değerlerinin güvenli karşılaştırması içinDouble.compare()kullanın.NameComparator.java: Çalışanları isme göre alfabetik olarak artan düzende (A'dan Z'ye) sıralayan başka bir comparator oluşturun.Comparator<Employee>arayüzünü uygulayın ve karşılaştırma için String sınıfınıncompareTo()metodunu kullanın.Main.java: Bir çalışan listesi oluşturup bunları comparator'larınızı kullanarak sıralayarak her şeyi bir araya getirin. Her biri ayrı bir satırda ve şu formatta olmak üzere üç çalışan için girdi alacaksınız:name,department,salaryÇalışanlardan oluşan bir
ArrayListoluşturun, ardından her iki sıralama yaklaşımını da gösterin:- Önce,
SalaryComparatorkullanarak maaşa göre sıralayın ve her çalışanı yazdırın - Boş bir satır yazdırın
- Ardından
NameComparatorkullanarak isme göre sıralayın ve her çalışanı yazdırın
- Önce,
Her biri şu formatta çalışan verilerini içeren üç satır girdi alacaksınız: name,department,salary
Örneğin, bir girdi satırı şöyle görünebilir: Alice,Engineering,75000.0
Comparator dosyalarınızda java.util.Comparator'ı, Main dosyanızda ise java.util.ArrayList, java.util.Collections ve java.util.Scanner'ı içe aktarmayı (import) unutmayın. Comparator'ların dışarıdan birden fazla sıralama stratejisi tanımlamanıza nasıl olanak tanıdığına dikkat edin; Employee sınıfının nasıl sıralanacağı hakkında hiçbir şey bilmesine gerek yoktur!
Kopya kağıdı
Comparator arayüzü, orijinal sınıfı değiştirmeden nesneleri sıralamak için harici karşılaştırma mantığı oluşturmanıza olanak tanır. Bu, birden fazla sıralama seçeneğine ihtiyaç duyduğunuzda kullanışlıdır.
Bir Comparator, compare() metodunu uygulayarak aynı türdeki iki nesneyi karşılaştırır:
import java.util.Comparator;
class NameComparator implements Comparator<Person> {
@Override
public int compare(Person p1, Person p2) {
return p1.getName().compareTo(p2.getName());
}
}Karşılaştırıcıyı (comparator) sıralama metodlarına aktarın:
Collections.sort(people, new NameComparator());Comparator işlevsel bir arayüz (functional interface) olduğu için kısa ve öz kod yazmak amacıyla lambda ifadelerini kullanabilirsiniz:
Collections.sort(people, (p1, p2) -> p1.getName().compareTo(p2.getName()));Sayısal değerleri karşılaştırmak için, güvenli karşılaştırma amacıyla Double.compare() gibi sarmalayıcı (wrapper) sınıf metodlarını kullanın:
class AgeComparator implements Comparator<Person> {
@Override
public int compare(Person p1, Person p2) {
return p1.getAge() - p2.getAge();
}
}Temel fark: Comparable sınıfın kendi içinde tek bir doğal sıralama tanımlarken, Comparator harici olarak sınırsız sayıda özel sıralama tanımlayabilen ayrı bir sınıftır.
Kendin dene
import java.util.ArrayList;
import java.util.Collections;
import java.util.Scanner;
class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
// Girdiden üç çalışanı oku
// Her satır formatı: name,department,salary
String line1 = scanner.nextLine();
String line2 = scanner.nextLine();
String line3 = scanner.nextLine();
// TODO: Her satırı ayrıştırın ve Employee nesneleri oluşturun
// Hint: Değerleri ayırmak için split(",") kullanın
// TODO: Çalışanlardan oluşan bir ArrayList oluşturun ve üçünü de ekleyin
// TODO: SalaryComparator kullanarak maaşa göre sıralayın ve her çalışanı yazdırın
// Hint: Collections.sort(list, comparator) kullanın
// TODO: Boş bir satır yazdırın
// TODO: NameComparator kullanarak isme göre sıralayın ve her çalışanı yazdırın
}
}
Bu ders kısa bir quiz içerir. Soruları yanıtlamak ve ilerlemeni kaydetmek için derse başla.
Nesne Yönelimli Programlama bölümündeki tüm dersler
1OOP Temelleri
Harici DosyalarOOP'ye GirişSınıflar ve Nesnelerthis Anahtar KelimesiMetotlarAlanlar (Öznitelikler)Yapıcı MetotYapıcı Metot Aşırı YüklemeÖzet - Basit Hesap Makinesi4Kalıtım
Temel Kalıtım (extends)super Anahtar KelimesiMetot Geçersiz Kılma (@Override)Yapıcı Metot ZincirlemeObject SınıfıTekli ve Çok Seviyeli KalıtımNeden Çoklu Sınıf Kalıtımı Yok?Özet - Çalışan Hiyerarşisi7Özel Metotlar ve Object Sınıfı
toString() Metoduequals() ve hashCode()clone() MetoducompareTo() ve ComparableComparator ArayüzüÖzet - Özel Sıralama2Erişim Belirleyiciler ve Kapsülleme
Erişim Seviyelerine Genel BakışGetter ve Setter MetotlarıBilgi Gizlemefinal Anahtar KelimesiÖzet - Banka Hesabı Yöneticisi5Polimorfizm
Metot Aşırı Yükleme TemelleriMetot Geçersiz Kılma (Çalışma Zamanı)Upcasting ve Downcastinginstanceof OperatörüSoyut Sınıflar ve MetotlarÖzet - Şekil Hesaplayıcı8İleri Düzey OOP Kavramları
Kompozisyon vs KalıtımAgregasyon vs KompozisyonDahili, Yuvalanmış ve Anonim SınıflarEnum'lar ve Enum MetotlarıRecords (Java 16+)Sealed Classes (Java 17+)11Tasarım Kalıpları Bölüm 1
Tasarım Kalıplarına GirişSingleton KalıbıFactory KalıbıBuilder KalıbıObserver KalıbıStrategy Kalıbı14Final Meydan Okumaları
E-Öğrenme PlatformuBankacılık SistemiOyun Karakteri GeliştirmeAraç Kiralama Servisi3Sınıf Özellikleri ve Statik Üyeler
Instance ve Statik DeğişkenlerStatik MetotlarStatik BloklarSabitler (static final)Özet - Sayaç ve Utility6Arayüzler ve Soyut Sınıflar
Arayüzlere GirişArayüzleri UygulamaÇoklu Arayüz UygulamaArayüzlerde Default ve StaticSoyut Sınıflar ve ArayüzlerFonksiyonel ArayüzlerÖzet - Ödeme Sistemi9Generics
Generics'e GirişGeneric SınıflarGeneric MetotlarSınırlandırılmış Tip ParametreleriWildcard'lar (?, extends, super)Özet - Generic Container12Tasarım Kalıpları Bölüm 2
Komut KalıbıAdaptör KalıbıDekoratör KalıbıŞablon Metot KalıbıDurum KalıbıKompozit KalıbıYineleyici Kalıbı