CodeGym/Java Blog/Random/Ang klase ng Comparator ng Java
John Squirrels
Antas
San Francisco

Ang klase ng Comparator ng Java

Nai-publish sa grupo
Hi! Ngayon ay pag-uusapan natin ang tungkol sa paghahambing ng mga bagay. Ang klase ng Comparator ng Java - 1 Hmm... Pero hindi ba't napag-usapan na natin ang paksang ito ng higit sa isang beses? :/ Alam namin kung paano ==gumagana ang operator, pati na rin ang equals()at hashCode()mga pamamaraan. Ang paghahambing ay medyo naiiba. Dati, malamang na ang ibig sabihin namin ay "pagsusuri ng mga bagay para sa pagkakapantay-pantay". Ngunit ang mga dahilan para sa paghahambing ng mga bagay sa bawat isa ay maaaring maging ganap na naiiba! Ang pinaka-halata sa mga ito ay ang pag-uuri. Sa palagay ko kung sasabihin sa iyo na pagbukud-bukurin ang isang ArrayList<>numero o mga string, magagawa mo ito nang walang anumang mga problema:
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);
   }
}
Output ng console:
[Dasha, Masha, Sasha]
Kung naalala mo ang Collectionsklase at sort()ang pamamaraan nito, magaling! Sa tingin ko hindi ka rin mahihirapan sa mga numero. Narito ang isang mas mapaghamong gawain para sa iyo:
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);
   }
}
Ang gawain ay talagang simple. Mayroon kaming isang Carklase at 3 bagay sa Kotse. Gusto mo bang ayusin ang mga kotse sa listahan? Marahil ay tatanungin mo, "Paano sila dapat ayusin?" Sa pangalan? Sa pamamagitan ng taon ng paggawa? Sa pinakamataas na bilis? Napakahusay na tanong. Sa ngayon, hindi namin alam kung paano ayusin ang Carmga bagay. At, medyo natural, hindi rin alam ng Java iyon! Kapag sinubukan naming ipasa ang isang listahan ng Carmga bagay sa Collections.sort()pamamaraan, nakakakuha kami ng isang error:
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);
   }
}
At sa katunayan, paano malalaman ng wika kung paano pag-uri-uriin ang mga bagay ng mga klase na iyong isinulat? Depende ito sa kung ano ang kailangang gawin ng iyong programa. Dapat nating turuan ang Java na ihambing ang mga bagay na ito. At upang ihambing ang mga ito kung paano natin gusto. Ang Java ay may espesyal na mekanismo para dito: ang Comparableinterface. Upang kahit papaano ay maihambing at maiuri ang aming Carmga bagay, dapat ipatupad ng klase ang interface na ito, na binubuo ng isang paraan: 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()

}
Paalalana tinukoy namin ang Comparable<Car>interface, hindi lang Comparable. Ito ay isang parameterized na interface, ibig sabihin, dapat nating tukuyin ang partikular na nauugnay na klase. Sa prinsipyo, maaari mong alisin <Car>mula sa interface, ngunit pagkatapos ay ang paghahambing ay ibabatay sa Objectmga bagay bilang default. Sa halip na ang compareTo(Car o)pamamaraan, ang aming klase ay magkakaroon ng:
@Override
   public int compareTo(Object o) {
       return 0;
   }
Siyempre, mas madali para sa amin na magtrabaho kasama si Car. Sa loob ng compareTo()pamamaraan, ipinapatupad namin ang aming lohika para sa paghahambing ng mga kotse. Ipagpalagay na kailangan nating ayusin ang mga ito ayon sa taon ng paggawa. Marahil ay napansin mo na ang compareTo()paraan ay nagbabalik ng isang int, hindi isang boolean. Huwag hayaang mabigla ka nito. Kapag inihambing natin ang dalawang bagay, mayroong 3 posibilidad:
  • а < b
  • a > b
  • a == b.
booleanmay 2 value lang: true at false, na hindi gumagana nang maayos para sa paghahambing ng mga bagay. Sa int, ang lahat ay mas simple. Kung ang return value ay > 0, then a > b. Kung ang resulta ng compareToay < 0, kung gayon a < b. At, kung ang resulta ay == 0, kung gayon ang dalawang bagay ay pantay-pantay: a == b. Ang pagtuturo sa aming klase na pagbukud-bukurin ang mga kotse ayon sa taon ng paggawa ay madaling peasy:
@Override
public int compareTo(Car o) {
   return this.getManufactureYear() - o.getManufactureYear();
}
Ngunit ano ang nangyayari dito? Kumuha kami ng isang bagay sa Kotse ( this), kunin ang taon ng paggawa ng sasakyang ito, at ibawas dito ang taon ng paggawa ng isa pang kotse (ang isa kung saan inihahambing ang bagay). Kung ang unang taon ng paggawa ng kotse ay mas malaki, ang pamamaraan ay magbabalik ng int > 0. Nangangahulugan ito na ang this car >kotse o. Sa kabaligtaran, kung ang taon ng paggawa ng pangalawang kotse ( о) ay mas malaki, ang pamamaraan ay magbabalik ng negatibong numero, na nangangahulugang o > this. Sa wakas, kung magkapantay sila, babalik ang pamamaraan 0. Ang simpleng mekanismong ito ay sapat na para pagbukud-bukurin natin ang mga koleksyon ng Carmga bagay! Wala ka nang ibang gagawin. Tingnan ito:
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);
   }
}
Output ng console:
[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}]
Ang mga kotse ay inayos ayon sa gusto namin! :) Ang klase ng Comparator ng Java - 2Kailan ko dapat gamitin Comparable? Ang pamamaraan ng paghahambing na ipinatupad sa Comparableay tinatawag na natural na pag-aayos. Ito ay dahil sa compareTo()paraang tinukoy mo ang pinakakaraniwan, o natural, na paraan ng paghahambing ng mga bagay ng klase na ito. Ang Java ay mayroon nang natural na pagkakasunod-sunod. Halimbawa, alam ng Java na ang mga string ay kadalasang pinagbubukod-bukod ayon sa alpabeto, at mga numero sa pamamagitan ng pagtaas ng numeric na halaga. Samakatuwid, kung tatawagin mo ang sort()pamamaraan sa isang listahan ng mga numero o mga string, pag-uuri-uriin ang mga ito. Kung ang aming programa ay karaniwang maghahambing at mag-uuri ng mga kotse ayon sa taon ng paggawa, dapat naming tukuyin ang natural na pag-uuri para sa Mga Kotse gamit ang Comparable<Car>interface at angcompareTo()paraan. Ngunit paano kung hindi ito sapat para sa atin? Isipin natin na ang ating programa ay hindi gaanong simple. Sa karamihan ng mga kaso, ang natural na pag-uuri ng mga kotse (na itinakda naming isagawa ayon sa taon ng paggawa) ay nababagay sa amin. Ngunit kung minsan ang aming mga customer ay mahilig sa mabilis na pagmamaneho. Kung naghahanda kami ng isang katalogo ng kotse para sa kanila upang bumasang mabuti, ang mga kotse ay dapat na pinagsunod-sunod ayon sa pinakamataas na bilis. Ang klase ng Comparator ng Java - 3Halimbawa, ipagpalagay na kailangan nating pag-uri-uriin ang ganito 15% ng oras. Ito ay malinaw na hindi sapat para sa amin upang itakda ang Carnatural na pag-uuri ng klase sa bilis sa halip na sa pamamagitan ng taon ng paggawa. Ngunit hindi namin maaaring balewalain ang 15% ng aming mga customer. Kaya ano ang gagawin natin? Isa pang interface ang tumulong sa amin dito: Comparator. Tulad ng Comparable, ito ay isang parameterized na interface. Ano ang pinagkaiba? Comparableginagawang "maihahambing" ang aming mga bagay at tinutukoy ang pinakanatural na pagkakasunud-sunod ng mga ito, ibig sabihin, ang pagkakasunud-sunod ng pag-uuri na gagamitin sa karamihan ng mga kaso. Comparatoray isang hiwalay na "paghahambing" na interface. Kung kailangan nating ipatupad ang ilang uri ng espesyal na pagkakasunud-sunod ng pag-uuri, hindi natin kailangang pumunta sa Carklase at baguhin ang lohika ng compareTo(). Sa halip, maaari tayong lumikha ng isang hiwalay na klase na nagpapatupad ng Comparator at ituro ito kung paano gawin ang pag-uuri na kailangan natin!
import java.util.Comparator;

public class MaxSpeedCarComparator implements Comparator<Car> {

   @Override
   public int compare(Car o1, Car o2) {
       return o1.getMaxSpeed() - o2.getMaxSpeed();
   }
}
Tulad ng nakikita mo, ang aming Comparatoray medyo simple. Kailangan nating ipatupad lamang ang isang paraan ng interface: compare(). Ito ay tumatagal ng dalawang Carbagay bilang mga input at inihahambing ang kanilang pinakamataas na bilis sa karaniwang paraan (sa pamamagitan ng pagbabawas). Tulad ng compareTo(), ibinabalik nito ang an int, at pareho ang prinsipyo ng paghahambing. Paano natin ito ginagamit? Ang lahat ng ito ay diretso:
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);
   }
}
Output ng console:
[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}]
Gumagawa lang kami ng comparator object at ipapasa ito sa Collections.sort()paraan kasama ang listahang pag-uuri-uriin. Kapag ang sort()pamamaraan ay nakatanggap ng isang comparator, hindi nito ginagamit ang natural na pag-uuri na tinukoy sa pamamaraan Carng klase compareTo(). Sa halip, inilalapat nito ang algorithm ng pag-uuri na tinukoy ng comparator na ipinasa dito. Ano ang mga pakinabang ng paggawa nito? Una, pagiging tugma sa umiiral na code. Gumawa kami ng bago, espesyal na paraan ng pag-uuri, habang pinapanatili ang umiiral na isa na gagamitin sa halos lahat ng oras. Hindi namin ginalaw ang Carklase. Ito ay isang Comparable, at nananatili itong:
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()

}
Pangalawa, flexibility. Maaari kaming magdagdag ng maraming algorithm ng pag-uuri ayon sa gusto namin. Halimbawa, maaari naming pag-uri-uriin ang mga kotse ayon sa kulay, bilis, timbang, o kung gaano karaming beses nagamit ang kotse sa mga pelikulang Batman. Ang kailangan lang nating gawin ay lumikha ng karagdagang Comparator. Ayan yun! Ngayon ay napag-aralan mo ang dalawang napakahalagang mekanismo na madalas mong gamitin sa mga totoong proyekto sa trabaho. Ngunit, tulad ng alam mo, ang teorya na walang kasanayan ay wala. Ngayon ay oras na upang pagsamahin ang iyong kaalaman at kumpletuhin ang ilang mga gawain!
Mga komento
  • Sikat
  • Bago
  • Luma
Dapat kang naka-sign in upang mag-iwan ng komento
Wala pang komento ang page na ito