CodeGym/Java Blogu/Rastgele/Java'nın Karşılaştırıcı sınıfı
John Squirrels
Seviye
San Francisco

Java'nın Karşılaştırıcı sınıfı

grupta yayınlandı
MERHABA! Bugün nesneleri karşılaştırma hakkında konuşacağız. Java'nın Karşılaştırıcı sınıfı - 1 Hmm... Ama bu konuyu zaten bir kereden fazla konuşmadık mı? ==:/ Operatörün nasıl çalıştığını ve ayrıca metodlarını equals()da biliyoruz hashCode(). Karşılaştırma biraz farklı. Önceden, büyük olasılıkla "eşitlik için nesnelerin kontrol edilmesi" demek istiyorduk. Ancak nesneleri birbiriyle karşılaştırma nedenleri tamamen farklı olabilir! Bunlardan en bariz olanı sıralamadır. Sanırım size bir sayı veya diziyi sıralamanız söylenseydi ArrayList<>, bunu sorunsuz bir şekilde halledebilirdiniz:
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class Main {

   public static void main(String[] args) {

       String name1 = "Masha";
       String name2 = "Sasha";
       String name3 = "Dasha";

       List<String> names = new ArrayList<>();
       names.add(name1);
       names.add(name2);
       names.add(name3);

       Collections.sort(names);
       System.out.println(names);
   }
}
Konsol çıktısı:
[Dasha, Masha, Sasha]
CollectionsSınıfı ve yöntemini hatırladıysanız sort(), aferin! Rakamlarla da sorun yaşamayacağınızı düşünüyorum. İşte size daha zorlu bir görev:
public class Car {

   private int manufactureYear;
   private String model;
   private int maxSpeed;

   public Car(int manufactureYear, String model, int maxSpeed) {
       this.manufactureYear = manufactureYear;
       this.model = model;
       this.maxSpeed = maxSpeed;
   }

   // ...getters, setters, toString()

}

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

public class Main {

   public static void main(String[] args) {

       List<Car> cars = new ArrayList<>();

       Car ferrari = new Car(1990, "Ferrari 360 Spider", 310);
       Car lambo = new Car(2012, "Lamborghini Gallardo", 290);
       Car bugatti = new Car(2010, "Bugatti Veyron", 350);

       cars.add(ferrari);
       cars.add(bugatti);
       cars.add(lambo);
   }
}
Görev aslında basit. CarBir sınıfımız ve 3 Araba nesnemiz var . Listedeki arabaları sıralar mısınız? Muhtemelen "Nasıl sıralanmalı?" diye soracaksınız. İsimle? Üretim yılına göre mi? Maksimum hıza göre mi? Mükemmel soru. Şu anda nesneleri nasıl sıralayacağımızı bilmiyoruz Car. Ve oldukça doğal olarak Java da bunu bilmiyor! CarYönteme bir nesne listesi iletmeye çalıştığımızda Collections.sort()bir hata alıyoruz:
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class Main {

   public static void main(String[] args) {

       List<Car> cars = new ArrayList<>();

       Car ferrari = new Car(1990, "Ferrari 360 Spider", 310);
       Car lambo = new Car(20012, "Lamborghini Gallardo", 290);
       Car bugatti = new Car(2010, "Bugatti Veyron", 350);

       cars.add(ferrari);
       cars.add(bugatti);
       cars.add(lambo);

       // Compilation error!
       Collections.sort(cars);
   }
}
Ve aslında, dil, yazdığınız sınıfların nesnelerini nasıl sıralayacağını nasıl bilecek? Bu, programınızın ne yapması gerektiğine bağlıdır. Bir şekilde Java'ya bu nesneleri karşılaştırmayı öğretmeliyiz. Ve onları tam istediğimiz gibi karşılaştırmak için. Java'nın bunun için özel bir mekanizması vardır: Comparablearayüz. Nesnelerimizi bir şekilde karşılaştırmak ve sıralamak için Car, sınıfın tek bir yöntemden oluşan bu arabirimi uygulaması gerekir: compareTo():
public class Car implements Comparable<Car> {

   private int manufactureYear;
   private String model;
   private int maxSpeed;

   public Car(int manufactureYear, String model, int maxSpeed) {
       this.manufactureYear = manufactureYear;
       this.model = model;
       this.maxSpeed = maxSpeed;
   }

   @Override
   public int compareTo(Car o) {
       return 0;
   }

   // ...getters, setters, toString()

}
lütfen aklınızda bulundurunarayüzü belirlediğimizi Comparable<Car>, sadece Comparable. Bu, parametreleştirilmiş bir arabirimdir, yani ilişkili belirli sınıfı belirtmemiz gerekir. <Car>Prensip olarak, arayüzden kaldırabilirsiniz , ancak daha sonra karşılaştırma Objectvarsayılan olarak nesnelere dayalı olacaktır. Yöntem yerine compareTo(Car o), sınıfımız şunları içerecektir:
@Override
   public int compareTo(Object o) {
       return 0;
   }
Tabii ki, onunla çalışmak bizim için çok daha kolay Car. Yöntemin içinde compareTo(), arabaları karşılaştırma mantığımızı uyguluyoruz. Bunları üretim yılına göre sıralamamız gerektiğini varsayalım. Muhtemelen yöntemin a değil compareTo()an döndürdüğünü fark etmişsinizdir . Bu seni şaşırtmasın. İki nesneyi karşılaştırdığımızda 3 olasılık vardır: intboolean
  • а < b
  • a > b
  • a == b.
booleanyalnızca 2 değeri vardır: doğru ve yanlış; bu, nesneleri karşılaştırmak için pek işe yaramaz. ile inther şey çok daha basit. Dönen değer ise > 0, o zaman a > b. sonucu ise compareTo, < 0o zaman a < b. Ve sonuç ise == 0, o zaman iki nesne eşittir: a == b. Sınıfımıza arabaları üretim yılına göre sıralamayı öğretmek kolaydır:
@Override
public int compareTo(Car o) {
   return this.getManufactureYear() - o.getManufactureYear();
}
Ama burada neler oluyor? Bir Araba nesnesini ( ) alıyoruz this, bu arabanın üretim yılını alıyoruz ve ondan başka bir arabanın (nesnenin karşılaştırıldığı) üretim yılını çıkarıyoruz. İlk otomobilin üretim yılı daha büyükse, yöntem bir int > 0. this car >Bu araba anlamına gelir o. Tersine, ikinci arabanın üretim yılı ( о) daha büyükse, yöntem negatif bir sayı döndürür, yani o > this. Son olarak, eşitlerse, yöntem döndürür 0. Bu basit mekanizma, nesne koleksiyonlarını sıralamamız için zaten yeterli Car! Başka bir şey yapmak zorunda değilsin. Buna bir bak:
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class Main {

   public static void main(String[] args) {

       List<Car> cars = new ArrayList<>();

       Car ferrari = new Car(1990, "Ferrari 360 Spider", 310);
       Car lambo = new Car(2012, "Lamborghini Gallardo", 290);
       Car bugatti = new Car(2010, "Bugatti Veyron", 350);

       cars.add(ferrari);
       cars.add(bugatti);
       cars.add(lambo);

       // There was previously an error here
       Collections.sort(cars);
       System.out.println(cars);
   }
}
Konsol çıktısı:
[Car{manufactureYear=1990, model='Ferrari 360 Spider', maxSpeed=310},
Car{manufactureYear=2010, model='Bugatti Veyron', maxSpeed=350},
Car{manufactureYear=2012, model='Lamborghini Gallardo', maxSpeed=290}]
Arabalar istediğimiz gibi sıralandı! :) Java'nın Karşılaştırıcı sınıfı - 2Ne zaman kullanmalıyım Comparable? Uygulanan karşılaştırma yöntemine Comparabledoğal sıralama denir. Bunun nedeni, yöntemde compareTo()bu sınıftaki nesneleri karşılaştırmanın en yaygın veya doğal yolunu tanımlamanızdır. Java zaten doğal bir sıralamaya sahiptir. Örneğin Java, dizelerin çoğunlukla alfabetik olarak sıralandığını ve sayıların sayısal değeri artırarak sıralandığını bilir. sort()Bu nedenle, yöntemi bir sayı veya dize listesinden çağırırsanız , bunlar sıralanır. Programımız genellikle otomobilleri üretim yılına göre karşılaştırıp sıralayacaksa, arayüzü kullanarak Otomobiller için doğal sıralamayı tanımlamamız gerekir Comparable<Car>.compareTo()yöntem. Ama ya bu bizim için yeterli değilse? Programımızın o kadar basit olmadığını düşünelim. Çoğu durumda, (üretim yılına göre gerçekleştirilecek şekilde ayarladığımız) arabaların doğal sıralaması bize uygundur. Ancak bazen müşterilerimiz hızlı sürüş meraklılarıdır. İncelemeleri için bir araba kataloğu hazırlıyorsak, arabalar maksimum hıza göre sıralanmalıdır. Java'nın Karşılaştırıcı sınıfı - 3Örneğin, zamanın %15'ini bu şekilde sıralamamız gerektiğini varsayalım. CarBu , sınıfın doğal sıralamasını üretim yılı yerine hıza göre ayarlamamız için açıkça yeterli değil . Ancak müşterilerimizin %15'ini görmezden gelemeyiz. Peki ne yapıyoruz? Burada yardımımıza başka bir arayüz geliyor: Comparator. Tıpkı Comparable, parametreleştirilmiş bir arayüzdür. Fark ne? Comparablenesnelerimizi "karşılaştırılabilir" kılar ve en doğal sıralama düzenini, yani çoğu durumda kullanılacak sıralama düzenini tanımlar. Comparatorayrı bir "karşılaştırma" arabirimidir. CarBir tür özel sıralama düzeni uygulamamız gerekirse, sınıfa girip mantığını değiştirmemize gerek yoktur compareTo(). Bunun yerine, Comparator'ı uygulayan ayrı bir sınıf oluşturabilir ve ona ihtiyacımız olan sıralamayı nasıl gerçekleştireceğini öğretebiliriz!
import java.util.Comparator;

public class MaxSpeedCarComparator implements Comparator<Car> {

   @Override
   public int compare(Car o1, Car o2) {
       return o1.getMaxSpeed() - o2.getMaxSpeed();
   }
}
Gördüğünüz gibi işimiz Comparatoroldukça basit. Yalnızca bir arabirim yöntemi uygulamamız gerekiyor: compare(). Girdi olarak iki nesne alır Carve bunların maksimum hızlarını olağan şekilde (çıkararak) karşılaştırır. gibi compareTo(), an değerini döndürür intve karşılaştırma ilkesi aynıdır. Bunu nasıl kullanırız? Her şey çok basit:
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

public class Main {

   public static void main(String[] args) {

       List<Car> cars = new ArrayList<>();

       Car ferrari = new Car(1990, "Ferrari 360 Spider", 310);
       Car lambo = new Car(2012, "Lamborghini Gallardo", 290);
       Car bugatti = new Car(2010, "Bugatti Veyron", 350);

       cars.add(ferrari);
       cars.add(bugatti);
       cars.add(lambo);

       Comparator speedComparator = new MaxSpeedCarComparator();
       Collections.sort(cars, speedComparator);

       System.out.println(cars);
   }
}
Konsol çıktısı:
[Car{manufactureYear=2012, model='Lamborghini Gallardo', maxSpeed=290},
Car{manufactureYear=1990, model='Ferrari 360 Spider', maxSpeed=310},
Car{manufactureYear=2010, model='Bugatti Veyron', maxSpeed=350}]
Collections.sort()Basitçe bir karşılaştırıcı nesne oluşturup sıralanacak listeyle birlikte yönteme iletiyoruz . Yöntem bir karşılaştırıcı aldığında , sınıfın sort()yönteminde tanımlanan doğal sıralamayı kullanmaz . Bunun yerine, kendisine iletilen karşılaştırıcı tarafından tanımlanan sıralama algoritmasını uygular. Bunu yapmanın avantajları nelerdir? İlk olarak, mevcut kodla uyumluluk. Çoğu zaman kullanılacak mevcut olanı korurken yeni, özel bir sıralama yöntemi oluşturduk. Sınıfa hiç dokunmadık . Bu bir idi ve bu yüzden kalır: CarcompareTo()CarComparable
public class Car implements Comparable<Car> {

   private int manufactureYear;
   private String model;
   private int maxSpeed;

   public Car(int manufactureYear, String model, int maxSpeed) {
       this.manufactureYear = manufactureYear;
       this.model = model;
       this.maxSpeed = maxSpeed;
   }

   @Override
   public int compareTo(Car o) {
       return this.getManufactureYear() - o.getManufactureYear();
   }

   // ...getters, setters, toString()

}
İkincisi, esneklik. İstediğimiz kadar sıralama algoritması ekleyebiliriz. Örneğin arabaları rengine, hızına, ağırlığına veya Batman filmlerinde bir arabanın kaç kez kullanıldığına göre sıralayabiliriz. Tek yapmamız gereken ek bir Comparator. Bu kadar! Bugün iş yerindeki gerçek projelerde sıklıkla kullanacağınız çok önemli iki mekanizmayı incelediniz. Ama bildiğiniz gibi pratik olmadan teori bir hiçtir. Şimdi bilginizi pekiştirme ve bazı görevleri tamamlama zamanı!
Yorumlar
  • Popüler
  • Yeni
  • Eskimiş
Yorum bırakmak için giriş yapmalısınız
Bu sayfada henüz yorum yok