L’interfaccia Comparator – Lezione 18 di Java Avanzato

Come ordinare con compare dell’interfaccia Comparator

Quando una classe ha bisogno di implementare diversi metodi di ordinamento, Java mette a disposizione l’interfaccia Comparator. Contenuta all’interno della libreria standard, Comparator rappresenta l’interfaccia corrispondente a Comparable. Viene usata per fornire più criteri di ordinamento ad una determinata classe a differenza di Comparable che ne fornisce solo uno. La sua struttura è la seguente:

  public interface Comparator {
    public int compare(Object x, Object y);
  }

Comparator possiede un contratto molto simile a quella di Comparable, in cui il metodo compare effettua il confronto tra due oggetti x e y. A differenza di Comparable, l’interfaccia Comparator non è fatta per essere implementata dalla classe stessa che vuole fornire gli ordinamento, in Comparator non ci sono riferimenti a this… quest’interfaccia è stata scritta soltanto per essere implementata da una classe sterna per ogni tipo di ordinamento.
Il suo uso è indicato quando la classe da ordinare non ha un unico criterio di ordinamento naturale, o quando è stata già realizzata e non può essere modificata.

Dati degli Employee potremmo utilizzare l’interfaccia Comparable per l’ordinamento naturale per nome e l’interfaccia Comparator per l’ordinamento (non naturale) sul salario facendola implementare da una classe esterna. In questo caso avremo:

  public class EmployeeComparatorBySalary implements Comparator {

    public int compare(Object x, Object y) {

      if(!(x instanceof Employee) || !(y instanceof Employee))
        throw new ClassCastException();

      Employee e1 = (Employee) x,
      e2 = (Employee) y;

      return e1.getSalary() - e2.getSalary();
    }

    //...
  }

Per ogni tipo di ordinamento creeremo un nuovo oggetto ogni qual volta vogliamo effettuare l’ordinamento. In realtà, ci basterebbe avere solo un unico oggetto per ogni classe che implementa Comparator e non crearlo ogni volta. Per far ciò possiamo utilizzare una costante di classe e rendere final il metodo. Inoltre, per non obbligare il client che vuole utilizzare l’ordinamento potremo dichiararlo static.
Infine, la classe esterna che viene definita in base ad un criterio di ordinamento può essere facilmente resa interna in modo che possa accedere direttamente ai campi della classe da ordinare.

Nell’esempio avremo che in Employee:

  public static final Comparator comparatorBySalary =
    new Comparator() {
      public int compare(Object x, Object y) {
        if(!(x instanceof Employee) || !(y instanceof Employee))
          throw new ClassCastException();
      Employee e1 = (Employee) x,
      e2 = (Employee) y;

      return e1.salary - e2.salary;
    }
  }

Ovviamente la classe resterà pubblica altrimenti nessun’altra classe esterna potrebbe ordinarla. Per poter utilizzare il nuovo ordinamento si può utilizzare il metodo statico sort di Collections, ad esempio per una lista:

  Collections.sort(lista, ClasseCheImplementaComparator);

L’ordinamento in String con Comparator

La classe String fornisce anche un ordinamento non case-sensitive, ovviamente dato che può esistere un unico ordinamento naturale, quest’altro tipo di ordinamento viene fornito da un oggetto di tipo Comparator. In String avremo una costante di classe che permetterà di implementare l’ordinamento non case-sensitive:

  public static final Comparator CASE_INSENSITIVE_ORDER;

Alla lezione 23 vedremo la versione parametrica della classe Comparator. Un ottimo riferimento per questa classe è la documentazione ufficiale di Java.

Indice Lezione PrecedenteLezione Successiva

nbsp;public static final Comparator CASE_INSENSITIVE_ORDER;

Pubblicato in Guide, Java, Programmazione Taggato con: , , , , , , ,

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *

*