Pagina 1 di 2 1 2 ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 18

Discussione: [java] Comparator

  1. #1

    [java] Comparator

    Non sto riuscendo a capire come implementare
    l'interfaccia Comparator,
    ammettiamo io devo ordinare un array di oggetti:
    codice:
    Object[] myObj = new Object[10];
    java.util.Arrays.sort(Object[] myObj, Comparator c);
    So che l'interfaccia dichiara due metodi:
    codice:
    boolean equals();
    int compare()
    Chi mi puo' fare un esempio molto semplice
    di come implementare questa interfaccia??

    Ciao
    Nulla, ma e' sempre qualcosa.

  2. #2
    Moderatore di Programmazione L'avatar di LeleFT
    Registrato dal
    Jun 2003
    Messaggi
    17,304
    Ho notato che Comparator è molto simile a Comparable che io ho proficuamente utilizzato più volte. In effetti Comparator richiede anche l'implementazione del metodo equals() che non è richiesta per Comparable.
    Se il tuo scopo è quello di poter ordinare un array di oggetti, allora ti consiglio di implementare Comparable (ti risparmi un metodo), comunque il metodo principale è uguale (cambia solamente il nome: per Comparator si chiama compare(), mentre per Comparable si chiama compareTo()).
    Quello che devi fare tu è implementare il metodo compare() in modo che restituisca un intero. Il numero intero che viene restituito deve seguire le seguenti regole:

    1) Deve essere negativo se il primo oggetto è minore del secondo oggetto;

    2) Deve essere uguale a 0 se i due oggetti sono uguali

    3) Deve essere maggiore di 0 se il primo oggetto è maggiore del secondo oggetto;
    Esempio: prendiamo questo piccolo esempio:
    codice:
    String s1 = "Abcd";
    String s2 = "Dcba";
    
    compare(s1, s2) --> ritorna un numero negativo
    compare(s1, s1) --> ritorna 0
    compare(s2, s1) --> ritorna un numero positivo
    Vediamo, quindi, un esempio di ordinamento, con una classe che implementa Comparable:
    codice:
    public class MioOggetto implements Comparator {
       private int[] mioDato;
       public MioOggetto() { mioDato = new int[2]; }
       public int [] getDato() { return mioDato; }
       public int compare(Object o1, Object o2) {
          /* Questo metodo effettua un ordinamento sulle coppie di interi
           * L'ordinamento è il seguente:
           * (A, B) < (C, D) se e solo se (A < C) oppure ((A = C) e (B < D))
           * (A, B) = (C, D) se e solo se (A = C) e (B = D)
           * altrimenti (A, B) > (C, D)
           */
    
           MioOggetto mo1 = (MioOggetto) o1;
           MioOggetto mo2 = (MioOggetto) o2;
           int [] altroDato1 = mo1.getDato();
           int [] altroDato2 = mo2.getDato();
           return (altroDato1[0] == altroDato2[0]) ?
                       altroDato1[1]-altroDato2[1] :
                       altroDato1[0]-altroDato2[0];
       }
    }
    Non ho fatto delle prove ma dovrebbe andare.

    A questo punto, se hai un array di MioOggetto, puoi passarli ad Arrays.sort() in questo modo:
    codice:
    MioOggetto [] array = ...;
    Arrays.sort( array );
    Ciao.
    "Perchè spendere anche solo 5 dollari per un S.O., quando posso averne uno gratis e spendere quei 5 dollari per 5 bottiglie di birra?" [Jon "maddog" Hall]
    Fatti non foste a viver come bruti, ma per seguir virtute e canoscenza

  3. #3
    ok Comparable e il suo utilizzo l'ho ben compreso,
    quindi posso dedurre che Comparator serve a
    generalizzare il cocetto di confronto tra due
    oggetti(minore o maggiore o uguale).

    Comparable e' un interfaccia che definisce un
    unico metodo (compareTo()).

    Mentre in Comparator i metodi sono due:
    boolean equals();//se due oggetti sono uguali
    int compare();//confronto di tipo alfabetico

    Ma essendo Comparator un'interfaccia
    non deve la classe che lo implementa
    ridefinire entrambi i metodi??

    Quindi il tuo esempio dovrebbe suscitare
    una protesta da parte del compilatore.
    Cmq non ho provato ancora quindi cio' che
    ho detto e' del tutto opinabile.
    :master:
    Nulla, ma e' sempre qualcosa.

  4. #4
    Moderatore di Programmazione L'avatar di LeleFT
    Registrato dal
    Jun 2003
    Messaggi
    17,304
    Originariamente inviato da maurizio2
    ok Comparable e il suo utilizzo l'ho ben compreso,
    quindi posso dedurre che Comparator serve a
    generalizzare il cocetto di confronto tra due
    oggetti(minore o maggiore o uguale).

    Comparable e' un interfaccia che definisce un
    unico metodo (compareTo()).

    Mentre in Comparator i metodi sono due:
    boolean equals();//se due oggetti sono uguali
    int compare();//confronto di tipo alfabetico

    Ma essendo Comparator un'interfaccia
    non deve la classe che lo implementa
    ridefinire entrambi i metodi??

    Quindi il tuo esempio dovrebbe suscitare
    una protesta da parte del compilatore.
    Cmq non ho provato ancora quindi cio' che
    ho detto e' del tutto opinabile.
    :master:
    Hai perfettamente ragione. Mi sono scordato di implementare il metodo equals() e ciò susciterà senza dubbio delle sonore proteste da parte del compilatore. La definizione del metodo equals(), comunque, è molto più sempilce del previsto:
    codice:
    public class MioOggetto implements Comparator {
       ...
       public boolean equals(Object o) {
          boolean risultato = false;
          if ( o instanceof MioOggetto) {
             MioOggetto mo = (MioOggetto) o;
             int [] dato = mo.getDato();
             risultato = (dato[0] == mioDato[0]) && (dato[1] == mioDato[1]);
          }
          return risultato;
       }
    }
    Credo che si potesse anche ricorrere al metodo equals() di Object, ma non ne sono proprio sicuro (basta provare):
    codice:
    public boolean equals(Object o) {
       return super.equals(o);
    }
    Ciao.
    "Perchè spendere anche solo 5 dollari per un S.O., quando posso averne uno gratis e spendere quei 5 dollari per 5 bottiglie di birra?" [Jon "maddog" Hall]
    Fatti non foste a viver come bruti, ma per seguir virtute e canoscenza

  5. #5
    Si equals() e' anche in Object
    ma implementando Comparator
    dovrebbe sopravvenire su quello ereditato
    da Object(premettendo sempre l'opinabilita').
    Dimmi se mi sbaglio...

    PS
    Dai un po' alla volta sto imparando anch'io
    Nulla, ma e' sempre qualcosa.

  6. #6
    Moderatore di Programmazione L'avatar di LeleFT
    Registrato dal
    Jun 2003
    Messaggi
    17,304
    Ho appena provato e funziona, anche se i risultati non sono esattamente quelli attesi!

    La documentazione di Comparator, comunque, afferma (giustamente) che le classi che implementano tale interfaccia dovrebbero ridefinire il metodo equals() senza far ricorso al metodo omonimo fornito dalla classe Object, in quanto quest'ultimo metodo dovrebbe essere inteso solo come misura di confronto.

    E' per questo che i risultati non tornano. Prendiamo, ad esempio, il seguente programma (ho aggiungo un costruttore alla classe MioOggetto di prima):
    codice:
    MioOggetto m1 = new MioOggetto(2, 3);
    MioOggetto m2 = new MioOggetto(2, 3);
    
    System.out.println( m1.equals(m2) );
    Se ridefiniamo il metodo equals() in modo che esso utilizzi il metodo equals() di Object, questo programma stampa false.

    Dal punto di vista semantico, comunque, questo potrebbe non soddisfarci: tutto sommato i due oggetti rappresentano la stessa coppia!

    Ecco perchè è bene ridefinire il metodo equals() nel modo che ho descritto precedentemente (senza ricorrere a super.equals() ).


    Ciao.
    "Perchè spendere anche solo 5 dollari per un S.O., quando posso averne uno gratis e spendere quei 5 dollari per 5 bottiglie di birra?" [Jon "maddog" Hall]
    Fatti non foste a viver come bruti, ma per seguir virtute e canoscenza

  7. #7
    Ok adesso mi e' chiara la differenza
    tra le due interfacce(Comparator & Comparable),
    devo imparare anche io....

    Ritornando all'esempio di prima
    codice:
    public class MioOggetto implements Comparator {
       ...
       public boolean equals(Object o) {
          boolean risultato = false;
          if ( o instanceof MioOggetto) {
             MioOggetto mo = (MioOggetto) o;
             int [] dato = mo.getDato();
             risultato = (dato[0] == mioDato[0]) && (dato[1] == mioDato[1]);
          }
          return risultato;
       }
    }
    non si potrebbe scrivere:
    codice:
    if(o.getClass().getName().equals(MioOggetto)){...}
    Premetto la leggittimita' di instanceof perche'
    sappiamo qui con certezza l'origine del dato.
    Nulla, ma e' sempre qualcosa.

  8. #8
    Moderatore di Programmazione L'avatar di LeleFT
    Registrato dal
    Jun 2003
    Messaggi
    17,304
    Originariamente inviato da maurizio2
    Ok adesso mi e' chiara la differenza
    tra le due interfacce(Comparator & Comparable),
    devo imparare anche io....

    Ritornando all'esempio di prima
    non si potrebbe scrivere:
    codice:
    if(o.getClass().getName().equals(MioOggetto)){...}
    Premetto la leggittimita' di instanceof perche'
    sappiamo qui con certezza l'origine del dato.
    Penso sia più corretto così :
    codice:
    if(o.getClass().getName().equals("MioOggetto")){...}
    Comunque dipende: se la tua classe non fa parte di alcun package, allora non hai problemi, altrimenti dovresti specificare anche tutto il package. Esempio, se sappiamo che l'oggetto passato è un Integer, che fa parte del package java.lang:
    codice:
    if (o.getClass().getName().equals("java.lang.Integer")) {...}
    Diciamo, quindi, che la parola chiave instanceof è più semplice da usare.


    Ciao.
    "Perchè spendere anche solo 5 dollari per un S.O., quando posso averne uno gratis e spendere quei 5 dollari per 5 bottiglie di birra?" [Jon "maddog" Hall]
    Fatti non foste a viver come bruti, ma per seguir virtute e canoscenza

  9. #9
    Moderatore di Programmazione L'avatar di LeleFT
    Registrato dal
    Jun 2003
    Messaggi
    17,304
    Sbagliato a cliccare.
    "Perchè spendere anche solo 5 dollari per un S.O., quando posso averne uno gratis e spendere quei 5 dollari per 5 bottiglie di birra?" [Jon "maddog" Hall]
    Fatti non foste a viver come bruti, ma per seguir virtute e canoscenza

  10. #10
    Era solo per capire...
    Cmq ho un libro pieno zeppo di errori
    e devo ammettere che e' un bene,
    il testo riporta l'esempio senza virgolette
    e ho corretto l'errore e volevo conferma....
    getName() restituisce una stringa del nome della
    classe di appartenenza.


    Potresti dire di provare di persona gli esempi
    ma io uso gia' digitare tutti gli esempi del libro a mano
    ma credo che teorizzare a parole gli esempi
    le cose si capiscano meglio!!!

    ciao
    Nulla, ma e' sempre qualcosa.

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2024 vBulletin Solutions, Inc. All rights reserved.