Logo
Ana Sayfa
ÖZEL KODLAMA DERSLERİ
Yazılım Özel Ders
Tüm birebir programlara genel bakış
Python Yazılım Kursu
Sıfırdan ileri seviyeye birebir Python
Java Yazılım Kursu
OOP odaklı birebir Java eğitimi
AP Computer Science Principles
AP CSP sınav hazırlığı
GRUP DERSLERİ
Python & Django Masterclass
SINIRLI KONTENJAN
Java & Spring Boot Masterclass
SINIRLI KONTENJAN
C# .NET Masterclass
SINIRLI KONTENJAN
VİDEO DERSLER
Sıfırdan Temel Python Kursu
Kendi Hızında Öğren
ÜCRETSİZ
Seviye Testi
Ücretsiz — Python, Java, algoritma seviye testleri
Kariyerini Keşfet
Sertifika Doğrula
Belge numarası ve soyad ile doğrulama

Java'da Comparable ve Comparator ile Nesne Sıralama

Yazar: Berk Keskin 28.08.2026 ~10 dk okuma 2 Okunma
java-comparable-comparator-nesne-siralama

Java'da Comparable ve Comparator arayüzleri, nesne koleksiyonlarını belirli bir kritere göre sıralamak için kullanılır; aralarındaki temel fark, Comparable'ın sınıfın kendi içinde tanımladığı tek bir "doğal sıralama" sağlaması, Comparator'ın ise sınıfın dışında tanımlanan ve istenildiği kadar çoğaltılabilen esnek sıralama kuralları sunmasıdır. Bir öğrenci listesini yaşa göre sıralamak istiyorsanız Comparable yeterli olabilir, ama aynı listeyi bazen isme bazen nota göre sıralamanız gerekiyorsa Comparator devreye girer. Bu yazıda compareTo ve compare metotlarının nasıl çalıştığını, hangi durumda hangisinin tercih edileceğini ve Collections.sort ile List.sort üzerinden pratik kullanımını adım adım ele alacağız.

Comparable Arayüzü Nedir ve compareTo Nasıl Çalışır?

Comparable, bir sınıfın nesnelerinin kendi aralarında nasıl sıralanacağını sınıfın içinden tanımlamasını sağlayan bir arayüzdür. Bir sınıf Comparable arayüzünü uyguladığında, içindeki tek bir metodu yazmak zorundadır: compareTo. Bu metot çağrıldığında, mevcut nesne ile parametre olarak verilen nesne karşılaştırılır ve sonucun anlamı üç duruma göre belirlenir.

  • Negatif bir değer dönerse, mevcut nesne parametredeki nesneden küçüktür (sıralamada önce gelir).
  • Pozitif bir değer dönerse, mevcut nesne parametredeki nesneden büyüktür (sıralamada sonra gelir).
  • Sıfır dönerse, iki nesne sıralama açısından eşit kabul edilir.

Bu mantık sayesinde Java, sıralama algoritmalarını (örneğin Collections.sort) her sınıfa özel yazmak zorunda kalmadan, sadece compareTo metodunun sonucuna bakarak çalıştırabilir. compareTo metodunun tanımladığı bu sıralama biçimine doğal sıralama denir; yani sınıfın "varsayılan" sıralama davranışıdır ve genellikle o sınıfın en anlamlı, en sık kullanılan alanına göre kurulur (örneğin bir Urun sınıfında fiyat, bir Ogrenci sınıfında öğrenci numarası gibi).

Aşağıdaki örnek, fiyatına göre doğal sıralamaya sahip basit bir Urun sınıfını göstermektedir:

public class Urun implements Comparable<Urun> {
    private double fiyat;

    public Urun(double fiyat) {
        this.fiyat = fiyat;
    }

    public double getFiyat() {
        return fiyat;
    }

    @Override
    public int compareTo(Urun diger) {
        return Double.compare(this.fiyat, diger.fiyat);
    }
}

Burada Double.compare metodu, iki double değeri karşılaştırıp negatif, pozitif veya sıfır döndürerek compareTo'nun beklediği sözleşmeyi otomatik olarak sağlar. Bir Urun listesi Collections.sort ile sıralandığında, Java arka planda bu compareTo metodunu çağırarak nesneleri fiyata göre küçükten büyüğe dizer. Doğal sıralama tek ve tutarlı olduğu sürece Comparable, sınıfın kendi kimliğinin bir parçası haline gelir ve o sınıfı kullanan her yerde aynı sıralama mantığı geçerli olur.

Comparator Arayüzü ve compare Metodu Farkı

Comparator, bir sınıfın kodunu değiştirmeden, o sınıfın nesneleri için dışarıdan bir sıralama kuralı tanımlamayı sağlayan ayrı bir arayüzdür. Comparable'dan en temel farkı burada başlar: compareTo sınıfın içinde, o sınıfa ait tek bir sıralama biçimini tanımlarken, Comparator'ın compare metodu sınıfın dışında yazılır ve aynı sınıf için birden fazla farklı sıralama kuralı oluşturulmasına izin verir.

compare metodu iki parametre alır (karşılaştırılacak iki nesne) ve compareTo ile aynı sözleşmeye uyar: negatif, pozitif veya sıfır döner. Aradaki fark metodun imzasında ve konumundadır; compareTo tek parametre alıp mevcut nesneyle kıyaslar, compare ise iki bağımsız nesneyi parametre olarak alıp aralarındaki ilişkiyi döndürür. Bu yapı, Comparator nesnelerinin ayrı sınıflar, iç sınıflar veya lambda ifadeleri olarak tanımlanmasına imkân tanır.

Comparator'ın asıl değeri, birden fazla sıralama ihtiyacı ortaya çıktığında görülür. Bir Ogrenci sınıfının doğal sıralaması öğrenci numarasına göre kurulmuş olabilir, ama bir ekranda isme göre, başka bir ekranda ortalama nota göre sıralama gerekebilir. Bu durumda sınıfın compareTo metodunu değiştirmek yerine, her ihtiyaç için ayrı bir Comparator tanımlanır ve Collections.sort ya da List.sort metoduna ikinci parametre olarak verilir. Bu yaklaşım, sınıfın kendisini bozmadan sıralama mantığını dışarıda çoğaltabilme esnekliği sağlar; nesne yönelimli tasarımda sorumlulukların ayrılması ilkesiyle de örtüşür. Konuyu uygulamalı örneklerle, gerçek proje senaryolarında pekiştirmek isteyenler için bire bir Java özel dersi kapsamında bu tür arayüz farkları adım adım kod üzerinde işlenir. compareTo ile compare arasındaki bu ayrım netleştikçe, hangi durumda hangi arayüzün seçileceği sorusu da doğal olarak çözülür.

Comparable mi Comparator mı? Seçim Kriteri

İki arayüz arasında seçim yaparken karmaşık kurallara gerek yoktur; birkaç net soruyu sırayla cevaplamak yeterlidir. Aşağıdaki adımlar bu kararı somutlaştırır.

  1. Sınıfın tek ve tutarlı bir doğal sıralaması var mı? Örneğin bir Para sınıfı için miktar her zaman anlamlı tek bir sıralama kriteriyse Comparable tercih edilir.
  2. Sınıfın kodunu değiştirme yetkiniz veya isteğiniz var mı? Kaynağına erişemediğiniz veya değiştirmek istemediğiniz bir sınıfı sıralamanız gerekiyorsa, Comparator zorunlu hale gelir çünkü compareTo eklemek mümkün değildir.
  3. Aynı sınıf için birden fazla sıralama senaryosu öngörülüyor mu? İsme göre, tarihe göre, tutara göre gibi farklı ihtiyaçlar varsa, her biri için ayrı bir Comparator tanımlamak Comparable'a göre çok daha sürdürülebilirdir.
  4. Sıralama kuralı geçici veya duruma özel mi? Tek seferlik, belirli bir ekranda kullanılacak bir sıralama ihtiyacıysa, sınıfın kalıcı sıralamasını değiştirmek yerine yerel bir Comparator (çoğunlukla lambda ile) yazmak daha temiz bir çözümdür.
  5. Sonuçları birleştirmek gerekiyor mu? Önce bir alana, eşitlik durumunda başka bir alana göre sıralama gibi çok kriterli senaryolarda Comparator, ek metotlarla zincirlenebildiği için daha uygundur.

Bu beş adım uygulandığında genel eğilim şu şekilde özetlenebilir: sınıfın kendi kimliğine ait, değişmeyen bir sıralama varsa Comparable; duruma göre değişen, dışarıdan tanımlanan veya birden fazla sıralama varsa Comparator kullanılır. Pratikte pek çok sınıf hem doğal sıralamasını Comparable ile tanımlar hem de ihtiyaç duyulan ek sıralama biçimleri için ayrı Comparator nesneleri barındırır; bu iki arayüz birbirini dışlamaz, aksine birlikte tamamlayıcı bir sıralama altyapısı oluşturur.

Comparable ve Comparator Karşılaştırma Tablosu

İki arayüz de nesneleri sıralamak için kullanılır, ancak konumlandıkları paket, taşıdıkları metot imzası ve pratikte tercih edilme sıklığı birbirinden farklıdır. Aşağıdaki tablo, önceki bölümlerde anlatılan ayrımları tek bakışta özetler ve hangi durumda hangi arayüzün daha uygun olduğunu netleştirir.

Kriter Comparable Comparator
Paket java.lang java.util
Metot compareTo(T o) compare(T o1, T o2)
Uygulanma yeri Sıralanacak sınıfın kendisi Ayrı bir sınıf, iç sınıf veya lambda ifadesi
Sıralama sayısı Sınıf başına yalnızca bir doğal sıralama Aynı sınıf için sınırsız sayıda alternatif sıralama
Amaç Nesnenin kendi doğal düzenini tanımlamak Duruma özgü, dışarıdan tanımlanan sıralama kuralları üretmek
Kullanım sıklığı Sınıfın tek ve sabit bir sıralama mantığı olduğunda tercih edilir Farklı ekranlarda, raporlarda veya filtrelerde değişken sıralama gerektiğinde tercih edilir

Tablodaki en kritik fark, sıralama sayısı satırıdır. Bir sınıfın yalnızca tek bir "doğal" hâli olabileceğinden Comparable o sınıfa gömülür; buna karşın gerçek dünyada aynı veri kümesini bazen isme, bazen tarihe, bazen tutara göre sıralamak gerekir ve bu esneklik yalnızca Comparator ile sağlanabilir.

Collections.sort ve List.sort ile Uygulama

Java koleksiyonlarını sıralamak için iki pratik yol vardır: Collections.sort() statik metodu ve List arayüzünün kendi sort() metodu. Her ikisi de aynı sonucu üretir; ikinci yöntem koleksiyonlar üzerine sonradan eklenmiş olup doğrudan liste nesnesi üzerinden çağrılabildiği için daha okunaklı kabul edilir. Bir sınıf Comparable arayüzünü uyguladıysa parametre vermeden çağrılır:

Collections.sort(ogrenciListesi);
// veya
ogrenciListesi.sort(null);

Comparator kullanılacaksa hem Collections.sort(liste, comparator) hem de liste.sort(comparator) geçerlidir. Comparator nesnesi ayrı bir sınıf yazmak yerine lambda ifadesiyle tek satırda tanımlanabilir; bu, gündelik kodlamada en çok tercih edilen yöntemdir:

ogrenciListesi.sort((o1, o2) -> o1.getNot() - o2.getNot());

Burada (o1, o2) -> ... yapısı, compare metodunun gövdesini doğrudan çağrı noktasında ifade eder; ayrı bir sınıf veya anonim sınıf yazmaya gerek kalmaz. Sayısal alanlarda çıkarma işlemiyle kısa yazım yaygın olsa da taşma riskine karşı Integer.compare(o1.getNot(), o2.getNot()) kullanımı daha güvenlidir. Comparator arayüzünün sunduğu Comparator.comparing(), thenComparing() ve reversed() gibi yardımcı metotlar da lambda ile birlikte zincirlenerek çok kriterli sıralamaları tek satıra indirger. Bu tür sıralama pratiklerini adım adım örneklerle pekiştirmek isteyenler, Java konulu diğer teknik yazılar arasında benzer koleksiyon işlemlerine dair uygulamalı anlatımlara ulaşabilir. Sıralama mantığını kavramak kadar, hangi metodun ne zaman çağrılacağını bilmek de kod okunabilirliği açısından önemlidir; liste küçükse ve tek seferlik bir işlemse lambda ile satır içi tanım yeterliyken, aynı sıralama mantığı projede tekrar tekrar kullanılacaksa bunu adlandırılmış bir metoda veya sabit bir Comparator nesnesine taşımak bakımı kolaylaştırır.

Ogrenci Sınıfı ile Çalışan Kod Örneği

Aşağıdaki örnek, aynı Ogrenci sınıfı üzerinde hem Comparable hem de Comparator kullanımını bir arada gösterir. Sınıf, Comparable arayüzünü uygulayarak isme göre doğal bir sıralama tanımlar; ardından nota göre sıralama ihtiyacı ortaya çıktığında bu iş, sınıfa dokunmadan bir lambda Comparator ile çözülür.

import java.util.ArrayList;
import java.util.List;

class Ogrenci implements Comparable<Ogrenci> {
    private String ad;
    private int not;

    public Ogrenci(String ad, int not) {
        this.ad = ad;
        this.not = not;
    }

    public String getAd() {
        return ad;
    }

    public int getNot() {
        return not;
    }

    @Override
    public int compareTo(Ogrenci digerOgrenci) {
        return this.ad.compareTo(digerOgrenci.ad);
    }

    @Override
    public String toString() {
        return ad + " - " + not;
    }
}

public class Uygulama {
    public static void main(String[] args) {
        List<Ogrenci> liste = new ArrayList<>();
        liste.add(new Ogrenci("Zeynep", 78));
        liste.add(new Ogrenci("Ahmet", 92));
        liste.add(new Ogrenci("Mert", 65));

        liste.sort(null);
        System.out.println("İsme göre: " + liste);

        liste.sort((o1, o2) -> o2.getNot() - o1.getNot());
        System.out.println("Nota göre (büyükten küçüğe): " + liste);
    }
}

Bu kodda liste.sort(null) çağrısı, Ogrenci sınıfının kendi compareTo tanımını kullanarak isim sırasına göre dizer; ikinci çağrıda ise dışarıdan verilen lambda, aynı listeyi hiçbir sınıf değişikliği yapmadan nota göre azalan sırayla dizer. İki yaklaşımın aynı sınıf üzerinde nasıl bir arada var olabildiğini görmek, Comparable ile Comparator arasındaki pratik farkı somutlaştırır. Konuyu kod üzerinden pekiştirdikten sonra öğrenilenleri ölçmek isteyenler Java bilgi seviyesini ölçen ücretsiz test ile sıralama ve arayüz konularındaki hakimiyetini kontrol edebilir. Sınıf yapısını değiştirmeden yeni bir sıralama kuralı eklemek gerektiğinde her zaman Comparator'a yönelmek, kodun ileride bakımını kolaylaştıran bir alışkanlıktır.

Sık Yapılan Hatalar ve Dikkat Noktaları

Comparable ve Comparator kullanırken en sık karşılaşılan sorunların büyük bölümü, compareTo metodunun hatalı yazılmasından kaynaklanır. Özellikle iki tam sayıyı doğrudan birbirinden çıkararak sonucu döndürmek yaygın bir alışkanlıktır; ancak sayı değerleri belirli sınırlara yaklaştığında bu işlem taşma (overflow) riski taşır ve beklenmedik sıralama sonuçları üretebilir. Bunun yerine Integer.compare() gibi statik yardımcı metotları kullanmak daha güvenlidir:

public int compareTo(Ogrenci diger) {
    return Integer.compare(this.not, diger.not);
}

Bir diğer önemli nokta, compareTo metodunun tutarlı davranmasıdır. Aynı iki nesne için compareTo her çağrıldığında aynı sonucu vermeli, ayrıca a.compareTo(b) pozitifse b.compareTo(a) negatif olmalıdır. Bu tutarlılık bozulduğunda sıralama algoritmaları kararsız sonuçlar üretebilir ve hata ayıklaması zor durumlar ortaya çıkar.

Birden fazla sabit Comparator tanımlayan projelerde de karışıklık sık görülür. Örneğin bir sınıf için hem isme göre hem tarihe göre sıralayan iki ayrı Comparator alanı tanımlandığında, bu alanlara açık ve anlamlı isimler vermek zorunludur; aksi hâlde hangi sıralamanın hangi alan tarafından sağlandığı zamanla unutulur ve yanlış Comparator'ın çağrılması sonucu yanlış sıralanmış listeler üretilir. Bu tür isimlendirme sorunları, özellikle büyüyen kod tabanlarında ciddi bakım maliyetine dönüşür.

Son olarak, sıralanacak listede veya karşılaştırılan alanlarda null değer bulunması durumunda çalışma zamanında NullPointerException alınması olasıdır; bu nedenle karşılaştırma yapılmadan önce ilgili alanın veya nesnenin null olup olmadığını kontrol etmek gerekir. Bu tür OOP prensiplerine dayalı ince noktaları uygulamalı olarak pekiştirmek isteyenler için birebir Java dersleri kapsamında bire bir geri bildirimle çalışmak, bu hataların erken fark edilmesini kolaylaştırır.

Sık Sorulan Sorular

Comparable ve Comparator arasındaki temel fark nedir?

Comparable, sıralama mantığının sınıfın kendi içinde compareTo metoduyla tanımlandığı ve sınıfın "doğal sırasını" belirlediği bir arayüzdür. Comparator ise sınıfın dışında, ayrı bir yapı içinde compare metoduyla tanımlanır ve aynı sınıf için birden fazla farklı sıralama kriteri oluşturulmasına imkân tanır.

Bir sınıfta hem Comparable hem Comparator birlikte kullanılabilir mi?

Evet, ikisi birbirini dışlamaz. Bir sınıf Comparable arayüzünü implemente ederek varsayılan bir doğal sırayı tanımlayabilir, aynı zamanda farklı ihtiyaçlar için ayrıca bir veya birden fazla Comparator nesnesi oluşturulabilir. Örneğin öğrenci sınıfı isme göre doğal sıralanırken, not veya yaşa göre sıralama için ayrı Comparator'lar tanımlanabilir.

compareTo metodu neden int değer döndürür?

int dönüş değeri, iki nesne arasındaki ilişkiyi tek bir sayıyla ifade etmenin pratik bir yoludur. Negatif değer çağıran nesnenin daha küçük olduğunu, pozitif değer daha büyük olduğunu, sıfır ise iki nesnenin sıralama açısından eşit kabul edildiğini gösterir. Bu basit kural, sıralama algoritmalarının tüm karşılaştırmaları tek tip bir mantıkla işleyebilmesini sağlar.

Lambda ile Comparator yazmak zorunlu mudur?

Hayır, zorunlu değildir. Comparator arayüzü anonim sınıf ile de klasik şekilde implemente edilebilir. Lambda ifadesi yalnızca kodu daha kısa ve okunabilir hâle getiren bir alternatiftir; işlevsel olarak aynı sonucu üretir ve tercih tamamen okunabilirlik ve alışkanlık meselesidir.

Sıralama sırasında NullPointerException neden oluşur?

Sıralanacak listede null bir eleman varsa veya karşılaştırılan nesnenin ilgili alanı null ise, compareTo veya compare metodu bu değer üzerinde işlem yapmaya çalıştığında çalışma zamanı hatası oluşur. Bu riski azaltmak için karşılaştırma öncesinde null kontrolü yapmak veya null değerleri sıralamadan önce listeden ayıklamak gerekir.

Comparable ve Comparator arayüzleri, Java'da nesne sıralamanın temelini oluşturur ve doğru kullanıldığında kod okunabilirliğini artırırken hatalı kullanıldığında sessiz ve tespiti zor hatalara yol açar. Bu tür nesne yönelimli programlama konularını uygulamalı örneklerle adım adım pekiştirmek isteyenler Java yazılım kursu sayfasından programın içeriğini inceleyebilir.

Bu içeriğin üretilmesinde yapay zeka araçlarından destek alınmıştır.

İlgili Eğitimler

Berk Keskin — Yazılım Geliştirici ve Eğitmen
Yazar

Berk Keskin Kimdir?

Yazılıma 12 yaşında başladı; bugün öğrencinin seviyesine ve hedefine göre şekillenen sürdürülebilir öğrenme sistemleri tasarlıyor. 300'den fazla kişiye ezber değil, düşünerek kod yazmayı öğretti — Berk Akademi'de izlemeye değil üretmeye dayalı öğrenme kültürünü o kuruyor.

WhatsApp Hemen Ara