Gyakorlati alapok III.
A Comparable interfész (a CompareTo() felülírása)
Ismételjük meg
előző fejezetünk utolsó gondolatait:
Olyan objektum esetén, amelyik nem valósítja meg a Comparable interfészt, a Collections.sort(objektum) hívásakor ClassCastException kivétel fog dobódni. Persze ez a metódushívás nagy baki, hiszen voltaképpen olyan dologgal próbáljuk az objektumot rendezni, amelyik nem is létezik, legalábbis nincs hozzácsatlakoztatva. A megoldás a Comparable interfész becsatlakoztatása és önálló összehasonlítási (vele rendezési) szempontok megadása.
A kérdés, hogy ezt miképpen tudjuk megoldani?
A Comparable interfész becsatlakoztatása könnyű (implements Comparable<>), amely voltaképpen csak egy, kidolgozatlan metódust tartalmaz, ez az int típusú compareTo(). Visszatérési értékei kötelezően a következők:
-
-1 - ha az objektum kisebb,
-
0 - ha objektum egyenlő,
-
1 - ha az objektum nagyobb.
Ebben a metódusban a megadott visszatérési értékek pontos figyelembevételével kell az összehasonlítási szempontot implementálnunk. Vegyünk erre egy szinte szabványosnak mondható példát!
Tételezzük fel, hogy van egy tanulói listánk, amely 2 elemet: nevet és érdemjegyet tartalmaz (tanuloNev és erdemJegy). Legyen a rendezési szempont az érdemjegyek növekvő sorrendje. A rendezési szempontot a compareTo() függvényben kell implementálnunk (felülírás - overriding, amelyet a kód az @Override szóval jelez), illetve érdemes egy kicsit az Object ősosztálytól örökölt toString() metódust is testreszabnunk:
import java.util.*;
class Main implements Comparable<Main>{
int erdemJegy;
String tanuloNev;
Main(int erdemJegy, String tanuloNev){
this.erdemJegy = erdemJegy;
this.tanuloNev = tanuloNev;
}
@Override
public int compareTo(Main obj) {
if(this.erdemJegy == obj.erdemJegy){
return 0;
}
else if(this.erdemJegy > obj.erdemJegy){
return 1;
}
else{
return -1;
}
}
@Override
public String toString(){
return tanuloNev + " erdemjegye: " + erdemJegy;
}
public static void main(String[] args) {
ArrayList<Main> tanulokListaja = new ArrayList<Main>();
tanulokListaja.add(new Main(2,"Zoltan"));
tanulokListaja.add(new Main(4,"Anna"));
tanulokListaja.add(new Main(5,"Hanna"));
tanulokListaja.add(new Main(1,"Arpad"));
tanulokListaja.add(new Main(3,"Kriszta"));
tanulokListaja.add(new Main(5,"Bela"));
Collections.sort(tanulokListaja);
for(Main elemek : tanulokListaja){
System.out.println(elemek);
}
}
}
Végeredmény:
Arpad erdemjegye: 1
Zoltan erdemjegye: 2
Kriszta erdemjegye: 3
Anna erdemjegye: 4
Hanna erdemjegye: 5
Bela erdemjegye: 5
Vegyük észre, hogy a compareTo() csupán egyetlen bemeneti paramétert vár (public int compareTo(Main obj)). Az esetek egyik részében ez elég is nekünk, a másikban azonban már nem, hiszen néha nem 1, hanem 2 objektumot szeretnénk összehasonlítani egymással. Pontosan erre a problémára ad megoldást a Comparator interfész, amelyet a következő fejezetben tanulmányozhatunk.