Comparable definisce quello che è il "natural order" (l'ordine naturale) tra gli elementi di una classe. Ciò significa che, se due o più elementi di una determinata classe devono essere comparati fra di loro per stabilire chi viene prima e chi dopo, è corretto far implementare Comparable a tale classe. In questo modo, la maggior parte delle funzioni di ordinamento "naturale" sapranno come ordinare gli elementi di quella classe.
Comparator, invece, definisce una funzione di ordinamento che potenzialmente nulla ha a che vedere con l'ordinamento normale (naturale) degli oggetti.
Facciamo un esempio. Supponiamo di avere una classe che contiene un campo String.
Tale campo String rappresenta un "ID" ed è anche il campo di ordinamento degli oggetti.
codice:
public class MiaClasse implements Comparable<MiaClasse> {
private String idClasse;
...
public String getIdClasse() { return idClasse; }
@Override
public int compareTo(MiaClasse mc) {
return this.idClasse.compareTo( mc.idClasse );
}
}
Questo è l'ordinamento "naturale" degli oggetti MiaClasse: ovvero, ordinando lessicograficamente le stringhe "idClasse" ottengo l'ordinamento degli oggetti.
Supponiamo, ora, che questo idClasse sia una stringa contenente un numero (il motivo di questa scelta implementativa non ci interessa). Un comparatore (Comparator) potrebbe voler mettere gli oggetti MiaClasse in ordine in base al valore numerico di questo ID (l'ordinamento lessicografico delle stringhe non tiene conto del valore numerico: "1000" verrà sempre prima di "2"). Ecco che posso costruire un Comparator che effettui questa cosa (posso implementare Comparator direttamente sulla classe o su un altro oggetto, quest'ultima è la scelta migliore) e dare in pasto un elenco di oggetti MiaClasse e il Comparator a Collections.sort() per ottenere l'ordinamento desiderato:
codice:
List<MiaClasse> lst = ... // Una lista di oggetti MiaClasse
Collections.sort(lst, new Comparator<MiaClasse>() {
@Override
public int compare(MiaClasse m1, MiaClasse m2) {
int val1 = Integer.parseInt(m1.getIdClasse());
int val2 = Integer.parseInt(m2.getIdClasse());
return val1 - val2;
}
});
In questo modo ordino i miei oggetti secondo il valore numerico del mio ID... ordinamento che esula completamente dall'ordinamento naturale degli elementi.
E posso costruire tanti comparatori quanti sono i tipi di ordinamento che mi interessano, anche più complessi di quello.
Ciao.