JavaRush /Блоги Java /Random-TG /Муқоисакунанда дар Java

Муқоисакунанда дар Java

Дар гурӯҳ нашр шудааст
Салом! Имрӯз мо дар бораи муқоисаи an objectҳо сӯҳбат хоҳем кард. Хм... Вале мо гуё дар ин бора на як бору ду бор гап задаем? :/ Мо медонем, ки ==оператори “ ” чӣ гуна кор мекунад, инчунин equals()усулҳои hashCode(). Муқоиса аслан дар ин бора нест. Пештар, мо бештар ба "озмоиши an objectҳо барои баробарӣ" монанд будем. Муқоисакунанда дар Java - 1Аммо муқоисаи ашё бо ҳамдигар метавонад ҳадафҳои тамоман дигар дошта бошад! Аз ҳама аёнтараш ҷудокунӣ мебошад. Ман фикр мекунам, агар ба шумо гуфта шавад, ки рӯйхати ArrayList<>рақамҳо ё сатрҳоро ҷудо кунед, шумо метавонед онро бе мушкилот ҳал кунед:
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);
   }
}
Натиҷаи консол:

[Даша, Маша, Саша]
Ин хеле хуб аст, агар шумо синф Collectionsва усули онро дар хотир дошта бошед sort(). Фикр намекунам, ки бо рақамҳо низ мушкилоте вуҷуд надорад. Ин аст вазифаи душвортаре барои шумо:
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);
   }
}
Ин хеле содда аст: синф Carва 3 an objectи он. Он қадар меҳрубон бошед, то мошинҳоро дар рӯйхат ҷудо кунед! Эҳтимол шумо мепурсед: "Онҳоро чӣ гуна бояд ҷудо кард?" Аз рӯи ном, аз рӯи соли истеҳсол, аз рӯи суръати максималӣ? Саволи олӣ. Мо дар айни замон намедонем, ки чӣ гуна an objectҳои синфро ҷудо кунем Car. Ва табиист, ки Java низ инро намедонад! Collections.sort()Вақте ки мо кӯшиш мекунем, ки рӯйхати an objectҳоро ба метод гузаронем Car, мо хатогиро мегирем:
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);
   }
}
Ва дар ҳақиқат, забон аз куҷо медонад, ки чӣ гуна an objectҳоеро, ки шумо менависед, ба ҳам ҷудо кунед? Ин аз ҳадафҳои барномаи шумо вобаста аст. Мо бояд ба ягон роҳ Java-ро омӯзем, ки ин an objectҳоро муқоиса кунад. Ва муқоиса кунед, ки мо ба он ниёз дорем. Барои ин Java дорои асбоби махсус - интерфейс мебошад Comparable. Дар забони англисӣ ин ҳамчун "муқоисашаванда" тарҷума шудааст. Барои он ки an objectҳои мо Carбо ҳамдигар муқоиса карда шаванд ва ба таври навъ ба тартиб оварда шаванд, синф бояд ин интерфейсро амалӣ кунад ва усули ягонаи худро амалӣ кунад: 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()

}
Диққат диҳед:Мо интерфейсро муайян кардем Comparable<Car>, на танҳо Comparable. Ин интерфейси чопшуда аст, яъне муайян кардани синфи мушаххасе, ки бо он алоқаманд аст, талаб мекунад. Аслан, <Car>шумо метавонед онро аз интерфейс хориҷ кунед, аммо он гоҳ an objectҳоро бо нобаёнӣ муқоиса мекунад Object. Ба ҷои усули compareTo(Car o)дар синфи мо мо дорои:
@Override
   public int compareTo(Object o) {
       return 0;
   }
Албатта, кор кардан барои мо хеле осонтар аст Car. Дар дохor усул compareTo()мо мантиқи муқоисаи мошинҳоро амалӣ мекунем. Фарз мекунем, ки мо бояд онҳоро аз рӯи соли истеҳсол ҷудо кунем. Шумо эҳтимол пай бурдед, ки усул compareTo()арзишро бармегардонад int, на boolean. Нагузоред, ки ин шуморо ба ҳайрат орад. Гап дар он аст, ки муқоисаи ду an object ба мо 3 имконоти имконпазирро медиҳад:
  • а < b
  • a > b
  • a == b.
Он booleanтанҳо 2 арзиш дорад - ҳақиқӣ ва дурӯғ, ки барои муқоисаи an objectҳо номувофиқ аст. intҲама чиз хеле соддатар аст . Агар арзиши бозгашт > 0бошад, пас a > b. Агар натиҷа compareTo < 0бошад, пас а < b. Хуб, агар натиҷа бошад == 0, он гоҳ ду an object баробаранд: a == b. Ба синфи мо омӯзонидани ҷудо кардани мошинҳо аз рӯи соли истеҳсол мисли тирпарронии нок осон аст:
@Override
public int compareTo(Car o) {
   return this.getManufactureYear() - o.getManufactureYear();
}
Дар ин ҷо чӣ гап? Мо як an objectи автомобorро ( this), соли истеҳсоли ин мошинро мегирем ва аз он соли истеҳсоли мошини дигарро (онеро, ки мо an objectро бо он муқоиса мекунем) тарҳ мекунем. Агар соли истеҳсоли мошини аввал калонтар бошад, усул бармегардад int > 0. Ин маънои онро дорад, ки мошин this >мошин аст о. Агар, баръакс, соли истеҳсоли мошини дуюм ( о) калонтар бошад, пас усул рақами манфиро бармегардонад ва бинобар ин о > this. Хуб, агар онҳо баробар бошанд, усул бармегардад 0. Чунин механизми оддӣ барои ҷудо кардани коллексияи an objectҳо кифоя аст Car! Ба шумо чизи дигаре лозим нест. Инҷо шумо ҳастед:
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);
   }
}
Натиҷаи консол:

[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}]
Мошинҳо тавре ки бояд бошад, ҷудо карда шудаанд! :) Муқоисакунанда дар Java - 2Дар кадом ҳолатҳо он бояд истифода шавад Comparable? Усули муќоисаи татбиќшаванда Comparable"тартиби табиї" номида мешавад. Сабаб дар он аст, ки шумо дар усул compareTo()усули маъмултарини муқоисаро тавсиф мекунед, ки барои an objectҳои ин синф дар барномаи шумо истифода мешавад. Тартиби табиӣ аллакай дар Java мавҷуд аст. Масалан, Java медонад, ки сатрҳо аксар вақт аз рӯи алифбо мураттаб карда мешаванд ва рақамҳо аксар вақт аз рӯи қимати афзоиш мураттаб карда мешаванд. Аз ин рӯ, агар шумо ин усулро дар рӯйхати рақамҳо ё сатрҳо даъват кунед sort(), онҳо мураттаб карда мешаванд. Comparable<Car>Агар дар барномаи мо мошинҳо дар аксари мавридҳо аз рӯи соли истеҳсол муқоиса ва ҷудо карда шаванд, пас барои онҳо бо истифода аз интерфейс ва усул навъҳои табииро муайян кардан лозим аст compareTo(). Аммо чӣ мешавад, агар ин барои мо кофӣ набошад? Тасаввур кунем, ки программам мо он кадар оддй нест. Дар аксар мавридхо ба навъбандии табиии мошинхо (мо онро аз руи соли истехсол мукаррар мекунем) ба мо мувофик аст. Аммо баъзан дар байни муштариёни мо ҳаводорони ронандагии тез пайдо мешаванд. Агар мо каталоги мошинҳоро барои интихоби онҳо омода кунем, онҳо бояд бо суръати максималӣ фармоиш дода шаванд. Муқоисакунанда дар Java - 3Масалан, дар 15 фоизи мавридхо ба мо чунин навъбандй лозим аст. Ин бешубҳа кифоя нест, ки Carба ҷои соли истеҳсолот ҷудокунии табиӣ аз рӯи суръат муқаррар карда шавад. Аммо мо наметавонем 15% муштариёнро нодида гирем. Мо чӣ кор мекунем? Дар ин ҷо интерфейси дигар ба кӯмаки мо меояд - Comparator. Мисли Comparableон, ки чоп карда мешавад. Фарқият чист? Comparablean objectҳои моро "муқоисашаванда" месозад ва барои онҳо тартиби табиии навъбандӣ эҷод мекунад, ки дар аксари ҳолатҳо истифода мешавад. Comparator- ин як синфи алоҳидаи "муқоисакунанда" аст (тарҷума каме нофаҳмо аст, аммо фаҳмо аст). Агар ба мо лозим аст, ки ягон навъбандии мушаххасро амалӣ кунем, мо набояд ба синф ворид шавем Carва мантиқро тағир диҳем compareTo(). Ба ҷои ин, мо метавонем дар барномаи худ як синфи муқоисакунандаи алоҳида эҷод кунем ва ба он омӯзем, ки ҷудокунии ба мо лозим аст!
import java.util.Comparator;

public class MaxSpeedCarComparator implements Comparator<Car> {

   @Override
   public int compare(Car o1, Car o2) {
       return o1.getMaxSpeed() - o2.getMaxSpeed();
   }
}
Тавре ки шумо мебинед, мо Comparatorхеле оддӣ аст. Танҳо як усул вуҷуд дорад compare()- ин усули интерфейс аст Comparator, ки бояд амалӣ карда шавад. Он ду an objectро ҳамчун вуруд мегирад Carва суръати максималии онҳоро бо роҳи муқаррарӣ муқоиса мекунад (бо тарҳ). Мисли compareTo(), он рақамро бармегардонад int, принсипи муқоиса ҳамон аст. Мо инро чӣ тавр истифода бурда метавонем? Хеле оддӣ:
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);
   }
}
Натиҷаи консол:

[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}]
Мо танҳо як an objectи муқоисакунандаро эҷод мекунем ва онро ба усул Collections.sort()дар якҷоягӣ бо рӯйхате, ки бояд мураттаб карда шавад, мегузарем. Бо гирифтани муқоисакунанда ҳамчун вуруд, усул ҷудокунии табиии дар усули синф sort()муайяншударо истифода намебарад . Ба ҷои ин, он алгоритми ҷудокуниро аз муқоисакунандае, ки ба он дода шудааст, татбиқ мекунад. Ин ба мо чӣ бартариҳо медиҳад? Аввалан, мутобиқат бо рамзи навишташуда. Мо усули нави хоси ҷудокуниро бо нигоҳ доштани усули ҷорӣ, ки дар аксари мавридҳо истифода мешавад, эҷод кардем. Мо ба синф тамоман даст нарасондем . Ӯ ҳамон тавре ки буд, монд: 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()

}
Дуюм, чандирӣ. Мо метавонем навъҳои зиёдеро, ки мехоҳем, илова кунем. Бигӯед, ки мошинҳоро аз рӯи ранг, суръат, вазн ё чанд маротиба дар филмҳои Батман истифода баред. Танҳо эҷоди як иловагӣ кофӣ аст Comparator. Ҳамааш ҳамин! Имрӯз шумо ду механизми хеле муҳимро омӯхтед, ки шумо аксар вақт дар лоиҳаҳои воқеӣ дар ҷои кор истифода хоҳед кард. Аммо, чунон ки шумо медонед, назария бе амалия чизе нест. Аз ин рӯ, вақти он расидааст, ки донишҳои худро мустаҳкам кунед ва якчанд мушкилотро ҳал кунед! :)
Шарҳҳо
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION