COME FARE SE I CRITERI DI CONFRONTO SONO MULTIPLI

Per poter confrontare gli oggetti di una classe la classe deve essere definita in modo da realizzare l'interfaccia Comparable. Ad esempio:

public class Studente implements Comparable
{
   private int matricola;
   privare String nome;

   public Studente(String n, int m)
   {
      nome = n;
      matricola = m;
   }

   public int matricola() { return matricola; }
   public String nome() { return nome; }
   public String toString() { return matricola + ":" + nome; }

   public int compareTo(Object obj)
   {
    ...
   }

}

Nel metodo int compareTo(Object obj) si programma il criterio di confronto degli oggetti confrontabili. Ad esempio se l'oggetto
di tipo Studente e' confrontabile secondo il numero di matricola:

   public int compareTo(Object obj)
   {
               Studente s = (Studente) obj;
      return matricola - s.matricola;

   }

Se per l'ordinamento si possono usare piu' criteri, in alternativa, bisogna programmarli nel metodo compareTo()
trovando il modo di eseguire di volta in volta solo la parte di codice relativa al criterio di ordinamento desiderato.

Questo si puo' fare definendo nella classe una variabile statica int criterio che puo' assumere vari valori:

  
public static int criterio;
   public static final int MATRICOLA = 0;
   public static final int NOME = 1;

   public StudenteEsteso(String n, int m)
   { super(n, m); } // costruttore della superclasse

   public int compareTo(Object obj) // metodo sovrascritto

   {
      Studente s = (Studente) obj;

      if (criterio == MATRICOLA)        

         return matricola - s.matricola;
      else if (criterio == NOME)
         return nome.compareTo(rhs.nome);
      else
         throw Illegal...
   }
Quando si voglia ordinare per matricola si deve porre la variabile criterio al
valore MATRICOLA:

  
StudenteEsteso.criterio = StudenteEsteso.MATRICOLA;

mentre quando si vuole ordinare per nome si deve porre la variabile criterio al
valore NOME;

   StudenteEsteso.criterio = StudenteEsteso.NOME;


Possiamo fare questo estendendo la classe Studente:

public class StudenteEsteso extends Studente
{
        //nuove variabili (di classe in questo caso)
   public static int criterio;
   public static final int MATRICOLA = 0;
   public static final int NOME = 1;

   public int compareTo(Object obj)  //override del metodo compareTo() della classe Studente

   {
      StudenteEsteso s = (StudenteEsteso) obj;

      if (criterio == MATRICOLA)        

         return matricola() - s.matricola();
      else if (criterio == NOME)
         return nome().compareTo(rhs.nome());
      else
         throw Illegal...
   }

}

Attenzione nel metodo compareTo() dobbiamo usare i metodi della superclasse nome() e matricola()
perche' le variabili di esemplare matricola e nome della classe Studente non sono accessibili nella sottoclasse.

Definire la variabile criterio come pubblica e' una violazione dell'incapsulamento. Nel metodo compareTo() si
verificano, pero', i valori asunti dalla classe.

Se la variabile criterio e' definita come privata, allora bisogna fornire un metodo ordinaPer(int crit) per modificare
la variabile criterio.