CodeGym /Blog Jawa /Acak /Kelas Komparator Jawa
John Squirrels
tingkat
San Francisco

# Kelas Komparator Jawa

Hi! Dina iki kita bakal ngomong babagan mbandhingake obyek. Hmm... Nanging apa ora kita wis ngomong topik iki luwih saka sepisan? : / We ngerti carane `==`operator dianggo, uga lan `equals()`cara `hashCode()`. Comparison punika sethitik beda. Sadurunge, kita paling kamungkinan tegese "mriksa obyek kanggo kesetaraan". Nanging alasan kanggo mbandhingake obyek bisa beda banget! Sing paling jelas yaiku ngurutake. Aku mikir yen sampeyan didhawuhi ngurutake `ArrayList<>`nomer utawa senar, sampeyan bakal bisa nangani iki tanpa masalah:
``````
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<>();

Collections.sort(names);
System.out.println(names);
}
}
``````
Output konsol:
``````
[Dasha, Masha, Sasha]
``````
Yen sampeyan ngelingi `Collections`kelas lan `sort()`cara, apik! Aku mikir sampeyan uga bakal ora masalah karo nomer. Mangkene tugas sing luwih tantangan kanggo sampeyan:
``````
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);

}
}
``````
Tugas kasebut pancen prasaja. Kita duwe `Car`kelas lan 3 obyek Mobil. Apa sampeyan pengin ngurutake mobil ing dhaptar? Sampeyan mbokmenawa bakal takon, "Carane kudu diurutake?" Miturut jeneng? Miturut taun produksi? Miturut kacepetan maksimum? Pitakonan sing apik banget. Saiki, kita ora ngerti carane ngurutake `Car`obyek kasebut. Lan, mesthi, Jawa uga ora ngerti! Nalika nyoba ngirim dhaptar `Car`obyek menyang `Collections.sort()`metode kasebut, kita entuk kesalahan:
``````
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);

// Compilation error!
Collections.sort(cars);
}
}
``````
Lan pancen, kepiye basa ngerti carane ngurutake obyek kelas sing wis ditulis? Iki gumantung apa sing kudu ditindakake program sampeyan. Kita kudu ngajari Jawa kanggo mbandhingake obyek kasebut. Lan kanggo mbandhingaké wong mung carane kita arep. Jawa duwe mekanisme khusus kanggo iki: `Comparable`antarmuka. Supaya bisa mbandhingake lan ngurutake `Car`obyek, kelas kasebut kudu ngetrapake antarmuka iki, sing kasusun saka siji cara: `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()

}
``````
Tulung dicathetsing kita nemtokake antarmuka `Comparable<Car>`, ora mung `Comparable`. Iki minangka antarmuka parameter, yaiku, kita kudu nemtokake kelas sing gegandhengan tartamtu. Ing asas, sampeyan bisa mbusak `<Car>`saka antarmuka, nanging banjur mbandhingaké bakal adhedhasar `Object`obyek minangka standar. Tinimbang metode `compareTo(Car o)`, kelas kita bakal duwe:
``````
@Override
public int compareTo(Object o) {
return 0;
}
``````
Mesthi, luwih gampang kanggo kita nggarap `Car`. Ing `compareTo()`cara kasebut, kita ngetrapake logika kanggo mbandhingake mobil. Contone, kita kudu ngurutake miturut taun produksi. Sampeyan mbokmenawa ngeweruhi sing `compareTo()`cara ngasilake a `int`, ora a `boolean`. Aja nganti sampeyan kaget. Nalika kita mbandhingake rong obyek, ana 3 kemungkinan:
• `а < b`
• `a > b`
• `a == b`.
`boolean`wis mung 2 nilai: bener lan salah, kang ora bisa uga kanggo mbandhingaké obyek. Kanthi `int`, kabeh luwih prasaja. Yen nilai bali `> 0`, banjur `a > b`. Yen asil saka `compareTo`, `< 0`banjur `a < b`. Lan, yen asile `== 0`, banjur rong obyek padha: `a == b`. Ngajari kelas kita ngurutake mobil miturut taun manufaktur gampang banget:
``````
@Override
public int compareTo(Car o) {
return this.getManufactureYear() - o.getManufactureYear();
}
``````
Nanging apa sing kedadeyan ing kene? Kita njupuk siji obyek Mobil ( `this`), entuk taun pabrik mobil iki, lan nyuda taun pabrikan mobil liyane (sing dibandhingake karo obyek kasebut). Yen taun produksi mobil pisanan luwih gedhe, cara kasebut bakal ngasilake `int > 0`. Iki tegese `this car >`mobil `o`. Kosok baline, yen taun pabrik mobil kapindho ( `о`) luwih gedhe, cara kasebut bakal ngasilake angka negatif, tegese `o > this`. Pungkasan, yen padha, cara kasebut bakal bali maneh `0`. Mekanisme prasaja iki wis cukup kanggo ngurutake koleksi `Car`obyek! Sampeyan ora kudu nindakake apa-apa liyane. Priksa metu:
``````
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);

// There was previously an error here
Collections.sort(cars);
System.out.println(cars);
}
}
``````
Output konsol:
``````
[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}]
``````
Mobil-mobil kasebut diurutake kaya sing dikarepake! :) Nalika aku kudu nggunakake `Comparable`? Metode perbandingan sing ditindakake ing `Comparable`diarani urutan alami. Iki amarga ing `compareTo()`cara sampeyan nemtokake cara sing paling umum, utawa alam, kanggo mbandhingake obyek saka kelas iki. Jawa wis duwe tatanan alam. Contone, Jawa ngerti yen strings paling kerep diurutake miturut abjad, lan angka kanthi nambah nilai numerik. Mulane, yen sampeyan nelpon `sort()`cara ing dhaptar nomer utawa strings, padha bakal diurutake. Yen program kita biasane mbandhingake lan ngurutake mobil miturut taun pabrik, mula kita kudu nemtokake pangurutan alami kanggo Mobil nggunakake antarmuka `Comparable<Car>`lan`compareTo()`cara. Nanging kepiye yen iki ora cukup kanggo kita? Ayo mbayangno program kita ora gampang banget. Umume kasus, ngurutake mobil alami (sing wis disetel kanggo ditindakake miturut taun pabrik) cocog karo kita. Nanging kadhangkala para pelanggan minangka penggemar nyopir kanthi cepet. Yen kita nyiapake katalog mobil kanggo maca, mobil kudu diurutake kanthi kacepetan maksimal. Contone, umpamane kita kudu ngurutake kaya iki 15% wektu. Iki jelas ora cukup kanggo nyetel `Car`urutan alam kelas kanthi kacepetan tinimbang taun pabrikan. Nanging kita ora bisa nglirwakake 15% pelanggan. Dadi apa sing kudu kita lakoni? Antarmuka liyane teka kanggo bantuan kita kene `Comparator`:. Kaya `Comparable`, iku antarmuka parameterized. Apa bedane? `Comparable`ndadekake obyek kita "dibandhingake" lan nemtokake urutan urutan sing paling alami, yaiku urutan urutan sing bakal digunakake ing akeh kasus. `Comparator`punika kapisah "mbandhingake" antarmuka. Yen kita kudu ngleksanakake sawetara jinis urutan ngurutake khusus, kita ora perlu kanggo pindhah menyang `Car`kelas lan ngganti logika saka `compareTo()`. Nanging, kita bisa nggawe kelas kapisah sing ngleksanakake Comparator lan mulang carane nindakake ngurutake kita kudu!
``````
import java.util.Comparator;

public class MaxSpeedCarComparator implements Comparator<Car> {

@Override
public int compare(Car o1, Car o2) {
return o1.getMaxSpeed() - o2.getMaxSpeed();
}
}
``````
Nalika sampeyan bisa ndeleng, kita `Comparator`cukup prasaja. Kita kudu ngleksanakake mung siji cara antarmuka: `compare()`. Butuh rong `Car`obyek minangka input lan mbandhingake kecepatan maksimal kanthi cara biasa (kanthi subtraction). Kaya `compareTo()`, ngasilake an `int`, lan prinsip perbandingan padha. Kepiye carane nggunakake iki? Iku kabeh langsung:
``````
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);

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

System.out.println(cars);
}
}
``````
Output konsol:
``````
[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}]
``````
Kita mung nggawe obyek komparator lan pass menyang `Collections.sort()`cara bebarengan karo dhaptar sing bakal diurutake. Nalika `sort()`cara nampa comparator a, ora nggunakake ngurutake alam ditetepake ing cara `Car`kelas kang `compareTo()`. Nanging, iki ditrapake algoritma pangurutan sing ditetepake dening komparator sing diwenehake. Apa kaluwihan saka nindakake iki? Pisanan, kompatibilitas karo kode sing ana. Kita nggawe anyar, cara ngurutake khusus, nalika nahan sing ana sing bakal digunakake paling wektu. Kita ora ndemek `Car`kelas babar pisan. Iku `Comparable`, lan tetep:
``````
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()

}
``````
Kapindho, keluwesan. Kita bisa nambah akeh algoritma ngurutake kaya sing dikarepake. Contone, kita bisa ngurutake mobil miturut warna, kacepetan, bobot, utawa kaping pirang-pirang mobil digunakake ing film Batman. Kabeh sing kudu kita lakoni yaiku nggawe tambahan `Comparator`. Mekaten! Dina iki sampeyan wis sinau rong mekanisme penting sing bakal kerep digunakake ing proyek nyata ing karya. Nanging, kaya sing sampeyan ngerteni, teori tanpa praktik ora ana apa-apa. Saiki wektune kanggo nggabungake kawruh lan ngrampungake sawetara tugas!
Komentar
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION