JavaRush /Java Blogu /Random-AZ /Java-da müqayisə

Java-da müqayisə

Qrupda dərc edilmişdir
Salam! Bu gün biz obyektlərin müqayisəsi haqqında danışacağıq. Hmm... Amma deyəsən bu barədə artıq bir dəfədən çox danışmışıq? :/ Biz “ ==” operatorunun necə işlədiyini, eləcə də equals()və üsullarını bilirik hashCode(). Müqayisə əslində bununla bağlı deyil. Əvvəllər biz daha çox “obyektləri bərabərlik üçün sınamaq” kimi nəzərdə tuturduq. Java-da müqayisəçi - 1Ancaq obyektləri bir-biri ilə müqayisə etmək tamamilə fərqli məqsədlərə sahib ola bilər! Ən bariz olanı çeşidləmədir. Düşünürəm ki, əgər sizə nömrələr və ya sətirlər siyahısını sıralamağınız deyilsə ArrayList<>, problemsiz idarə edə bilərsiniz:
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 = "Даша";

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

       Collections.sort(names);
       System.out.println(names);
   }
}
Konsol çıxışı:

[Даша, Маша, Саша]
CollectionsSinfi və onun metodunu xatırlasanız əla olar sort(). Rəqəmlərlə bağlı da problem olacağını düşünmürəm. Budur sizin üçün daha çətin bir iş:
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;
   }

   //...геттеры, сеттеры, 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);
   }
}
Çox sadədir: sinif Carvə onun 3 obyekti. Siyahıdakı avtomobilləri sıralamaq üçün mehriban olun! Yəqin ki, soruşacaqsınız: "Onları necə sıralamaq lazımdır?" Adına görə, istehsal ilinə görə, maksimum sürətə görə? Əla sual. Hal-hazırda sinfin obyektlərini necə sıralayacağımızı bilmirik Car. Və təbii ki, Java da bunu bilmir! Collections.sort()Obyektlərin siyahısını metoda ötürməyə çalışdığımız zaman Carxəta alacağıq:
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);

       //ошибка компилятора!
       Collections.sort(cars);
   }
}
Və həqiqətən, dil yazdığınız obyektləri necə sıralamağı dəqiq necə bilir? Bu, proqramınızın məqsədlərindən asılıdır. Bu obyektləri müqayisə etməyi birtəhər Java-ya öyrətməliyik. Və ehtiyacımız olan yolu müqayisə edin. Bunun üçün Java-nın xüsusi aləti - interfeysi var Comparable. İngilis dilində bu "müqayisə edilə bilən" kimi tərcümə olunur. CarObyektlərimizin bir-biri ilə müqayisə edilməsi və bir növ sıralanması üçün sinif bu interfeysi həyata keçirməli və yeganə metodunu həyata keçirməlidir: 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;
   }

   //...геттеры, сеттеры, toString()

}
Diqqət edin:biz interfeysi müəyyən etdik Comparable<Car>, təkcə Comparable. Bu tipli interfeysdir, yəni əlaqəli olduğu xüsusi sinfi göstərməyi tələb edir. Prinsipcə, <Car>siz onu interfeysdən silə bilərsiniz, lakin sonra o, standart olaraq obyektləri müqayisə edir Object. compareTo(Car o)Sinifimizdə metod əvəzinə bizdə olacaq:
@Override
   public int compareTo(Object o) {
       return 0;
   }
Əlbəttə ki, bizim üçün işləmək daha asandır Car. Metodun içərisində compareTo()biz maşınları müqayisə etmək üçün məntiqi həyata keçiririk. Tutaq ki, onları istehsal illərinə görə çeşidləmək lazımdır. Yəqin ki, metodun dəyəri deyil, compareTo()dəyəri qaytardığını fərq etdiniz . Bunun sizi təəccübləndirməsinə imkan verməyin. Fakt budur ki, iki obyekti müqayisə etmək bizə 3 mümkün variant verir: intboolean
  • а < b
  • a > b
  • a == b.
Onun booleanyalnız 2 dəyəri var - doğru və yanlış, bu, obyektləri müqayisə etmək üçün əlverişsizdir. Hər şey intdaha sadədir. Qaytarılan dəyər olarsa > 0, onda a > b. Nəticə olarsa compareTo < 0, deməli а < b. Yaxşı, əgər nəticə olarsa == 0, onda iki obyekt bərabərdir: a == b. Sinifimizə avtomobilləri istehsal illərinə görə çeşidləməyi öyrətmək armudları atəşə tutmaq qədər asandır:
@Override
public int compareTo(Car o) {
   return this.getManufactureYear() - o.getManufactureYear();
}
Burda nə baş verir? Bir avtomobil obyektini ( ), bu avtomobilin istehsal ilini götürürük thisvə ondan başqa bir avtomobilin istehsal ilini (obyekti müqayisə etdiyimiz) çıxarırıq. İlk avtomobilin istehsal ili daha böyükdürsə, üsul geri qayıdacaq int > 0. Bu o deməkdir ki, avtomobil this >avtomobildir о. Əksinə, ikinci avtomobilin istehsal ili ( о) daha böyükdürsə, üsul mənfi bir rəqəm qaytaracaq və buna görə də о > this. Yaxşı, əgər onlar bərabərdirsə, metod geri qayıdacaq 0. Belə sadə mexanizm obyektlərin kolleksiyalarını çeşidləmək üçün artıq kifayətdir Car! Başqa bir şey etmək lazım deyil. Buyurun:
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);

       //тут раньше была ошибка
       Collections.sort(cars);
       System.out.println(cars);
   }
}
Konsol çıxışı:

[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}]
Maşınlar lazım olduğu kimi sıralanır! :) Java-da müqayisə aparatı - 2Hansı hallarda istifadə edilməlidir Comparable? Tətbiq olunan müqayisə üsulu Comparable“təbii sifariş” adlanır. Bunun səbəbi, metodda compareTo()proqramınızda bu sinif obyektləri üçün istifadə ediləcək ən ümumi müqayisə metodunu təsvir etməyinizdir. Təbii sifariş artıq Java-da mövcuddur. Məsələn, Java bilir ki, sətirlər ən çox əlifba sırası ilə, nömrələr isə artan qiymətə görə sıralanır. Buna görə də, metodu nömrələr və ya sətirlər siyahısında çağırsanız sort(), onlar çeşidlənəcəklər. Proqramımızda avtomobillər əksər hallarda istehsal illərinə görə müqayisə ediləcək və çeşidlənəcəksə, o zaman interfeys Comparable<Car>və metoddan istifadə edərək onlar üçün təbii çeşidi müəyyən etməyə dəyər compareTo(). Bəs bu bizim üçün kifayət deyilsə? Təsəvvür edək ki, proqramımız o qədər də sadə deyil. Əksər hallarda avtomobillərin təbii çeşidlənməsi (biz onu istehsal ilinə görə təyin edirik) bizə uyğun gəlir. Ancaq bəzən müştərilərimiz arasında sürətli sürücülük həvəskarları olur. Əgər biz onlar üçün avtomobillərin kataloqunu hazırlayırıqsa, onları maksimum sürətə görə sifariş etmək lazımdır. Java-da müqayisə aparatı - 3Məsələn, 15% hallarda belə çeşidləmə bizə lazımdır. CarBu, təbii çeşidləmənin istehsal ili əvəzinə sürətə görə təyin edilməsi üçün kifayət deyil . Amma biz müştərilərin 15%-ni gözardı edə bilmərik. Biz nə edirik? Burada başqa bir interfeys köməyimizə gəlir - Comparator. Necə ki, Comparableyazılır. Fərq nədir? Comparableobyektlərimizi "müqayisə edilə bilən" edir və onlar üçün əksər hallarda istifadə olunacaq ən təbii çeşidləmə qaydasını yaradır. Comparator- bu ayrıca "müqayisəli" sinifdir (tərcümə bir az yöndəmsiz, lakin başa düşüləndir). CarƏgər hansısa xüsusi çeşidləmə həyata keçirməli olsaq, sinfə girib məntiqi dəyişməli deyilik compareTo(). Bunun əvəzinə proqramımızda ayrıca müqayisəli sinif yarada və ona lazım olan çeşidləməni etməyi öyrədə bilərik!
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üyünüz kimi, bizimki Comparatorolduqca sadədir. Yalnız bir üsul var compare()- bu bir interfeys üsuludur Comparator, həyata keçirilməlidir. O, iki obyekti daxil edir Carvə onların maksimal sürətini adi şəkildə müqayisə edir (çıxma ilə). Kimi compareTo(), rəqəmi qaytarır int, müqayisə prinsipi eynidir. Bundan necə istifadə edə bilərik? Çox sadə:
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 çıxışı:

[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()Biz sadəcə olaraq müqayisə obyekti yaradırıq və onu çeşidlənəcək siyahı ilə birlikdə metoda ötürürük . Giriş kimi müqayisəedici qəbul etdikdən sonra metod sinif sort()metodunda müəyyən edilmiş təbii çeşidləmədən istifadə etməyəcək . Bunun əvəzinə, ona ötürülən müqayisəçidən çeşidləmə alqoritmini tətbiq edəcək. Bu bizə hansı üstünlükləri verir? Birincisi, yazılı kodla uyğunluq. Əksər hallarda istifadə olunacaq mövcud olanı saxlayaraq yeni, spesifik çeşidləmə metodu yaratdıq. Biz ümumiyyətlə sinfə toxunmadıq . O, olduğu kimi qaldı: compareTo()CarCarComparable
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();
   }

   //...геттеры, сеттеры, toString()

}
İkincisi, elastiklik. İstədiyimiz qədər çeşid əlavə edə bilərik. Deyin ki, avtomobilləri rənginə, sürətinə, çəkisinə və ya avtomobilin Batman filmlərində neçə dəfə istifadə edildiyinə görə sıralayın. Yalnız əlavə bir yaratmaq kifayətdir Comparator. Hamısı budur! Bu gün siz iş yerində real layihələrdə tez-tez istifadə edəcəyiniz iki çox vacib mexanizm öyrəndiniz. Ancaq bildiyiniz kimi, praktikasız nəzəriyyə heç bir şey deyil. Buna görə də, biliklərinizi möhkəmləndirməyin və bir neçə problemi həll etməyin vaxtı gəldi! :)
Şərhlər
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION