Visualizzazione dei risultati da 1 a 8 su 8
  1. #1
    Utente di HTML.it
    Registrato dal
    Dec 2007
    Messaggi
    20

    [JAVA]-E' male chiamare equals() nel corpo di compareTo()?

    Dato che compareTo() dovrebbe, ove possibile, essere consistente con equals() è male chiamare equals() dentro al corpo del metodo compareTo() per la determinazione dell'uguaglianza fra due oggetti?

    Se l'implementazione dell'algoritmo di uguaglianza è abbastanza lungo, richiamando equals() dentro a compareTo() si riutilizzarebbe un bel po' di codice per stabilire l'uguaglianza fra due oggetti da comparare e si garantirebbe la consistenza con compareTo().

    E' una pratica lecita o è meglio implementare nuovamente l'algoritmo di uguaglianza anche nel corpo di compareTo() senza ricorrere alla scorciatoia di richiamare equals()?

    grazie per l'attenzione.

  2. #2
    Utente di HTML.it
    Registrato dal
    Dec 2007
    Messaggi
    20

  3. #3
    Moderatore di Programmazione L'avatar di LeleFT
    Registrato dal
    Jun 2003
    Messaggi
    17,328
    Non vedo proprio cosa ci sia di male.
    Se già equals() svolge il lavoro per controllare l'uguaglianza fra due oggetti, non vedo che cosa ci possa essere di male nel riutilizzarla... la programmazione "procedurale" è nata proprio per questo.

    Certo, se esiste un modo più rapido per la comparazione, sarebbe meglio implementarlo...

    Quello che mi chiedo io è cosa c'entri equals() con compareTo()...

    compareTo() deve restituire un intero che indica se l'oggetto che sto testando è minore, maggiore o uguale a quello passato come parametro... equals() avrebbe senso solo per rispondere al terzo caso... e gli altri due?


    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

  4. #4
    Utente di HTML.it
    Registrato dal
    Dec 2007
    Messaggi
    20
    Quello che mi chiedo io è cosa c'entri equals() con compareTo()...
    compareTo() deve stabilire anche se i due oggetti sono uguali e nel farlo è meglio che sia consistente con equals().

    compareTo() deve restituire un intero che indica se l'oggetto che sto testando è minore, maggiore o uguale a quello passato come parametro... equals() avrebbe senso solo per rispondere al terzo caso... e gli altri due?
    Gli altri due li implementi appunto in compareTo(). Per l'uguaglianza se il codice è lungo torna comodo usare equals() però nei testi che ho consultato non viene mai fatto quindi mi sono chieso: non è che per caso non viene fatto perchè ci sono delle controindicazioni?

  5. #5
    Utente di HTML.it L'avatar di Pastore12
    Registrato dal
    Oct 2008
    Messaggi
    1,051
    credo che non venga fatto perchè una risposta positiva di equals in questo contesto (compareTo) è in genere rarissima. Se devi confrontare un oggetto O con una collezione di oggetti quanti oggetti della collezione avaranno gli stessi valori di O? In genere pochi, e quanti di essi saranno esattamente O? Una miseria.. probabilmente fare il cotrollo su equals rende l'algoritmo più lento perchè nel 99,9% dei casi la risposta sarà false.

    A parte questo, non ci sono motivi che dia errore.
    "Ethics are to me something private. Whenever you use it as an argument for why somebody_else should do something, you’re no longer being ethical, you’re just being a sanctimonious dick-head"
    Linus Torvalds

  6. #6
    Utente di HTML.it
    Registrato dal
    Dec 2007
    Messaggi
    20
    probabilmente fare il cotrollo su equals rende l'algoritmo più lento perchè nel 99,9% dei casi la risposta sarà false.
    A parte questo, non ci sono motivi che dia errore.
    Basta metterlo in una serie di if-else per ultimo: ecco che la chiamata ad equals() verrà effettuata SOLO nei casi in cui i due oggetti non sono uno maggiore dell'altro nè uno minore dell'altro.

  7. #7
    Utente di HTML.it L'avatar di Pastore12
    Registrato dal
    Oct 2008
    Messaggi
    1,051
    Basta metterlo in una serie di if-else per ultimo: ecco che la chiamata ad equals() verrà effettuata SOLO nei casi in cui i due oggetti non sono uno maggiore dell'altro nè uno minore dell'altro.
    Forse sto facendo un po' di confusione.. Hai ragione se il metodo equals dell'oggetto non è il metodo equals di Object.
    Metti che stai creando un tuo tipo di dato che implementa l'interfaccia Comparable.
    Allora implementi il metodo compareTo, ok?
    Se nel compareTo vuoi usare il metodo equals, allora lo devi implementare (equals), perchè se non lo fai equals equivale a == (cioè è l'equals di Object che chiami).

    A questo punto, se implementi sia equals che compareTo è ininfluente che usi equals nel compareTo oppure implementi equals chiamando compareTo.

    ok, ora chiudo che si lavora.. Ciao!
    "Ethics are to me something private. Whenever you use it as an argument for why somebody_else should do something, you’re no longer being ethical, you’re just being a sanctimonious dick-head"
    Linus Torvalds

  8. #8
    Moderatore di Programmazione L'avatar di LeleFT
    Registrato dal
    Jun 2003
    Messaggi
    17,328
    Originariamente inviato da HKfly
    compareTo() deve stabilire anche se i due oggetti sono uguali e nel farlo è meglio che sia consistente con equals().
    E fin qui siamo perfettamente d'accordo.

    Gli altri due li implementi appunto in compareTo(). Per l'uguaglianza se il codice è lungo torna comodo usare equals() però nei testi che ho consultato non viene mai fatto quindi mi sono chieso: non è che per caso non viene fatto perchè ci sono delle controindicazioni?
    Il problema, a questo punto, non è tanto capire se sia corretto o meno utilizzare equals() all'interno di compareTo() (come abbiamo appurato, non c'è nessuna controindicazione in termini di correttezza), ma è capire se sia "conveniente" dal punto di vista algoritmico e dal punto di vista delle performances.

    Algoritmicamente potrebbe essere sconsigliato se i test effettuati per rilevare la discordanza fra i due oggetti sono gli stessi (o similari) utilizzati da equals() per rilevarne l'identità: in questo caso, probabilmente, con poche modifiche all'algoritmo iniziale (quello che rileva se l'oggetto è minore o maggiore di quello passato) si ottiene un algoritmo in grado di fornire una risposta anche per l'uguaglianza.

    Il punto di vista delle performance è spesso legato al punto precedente: se una modifica all'algoritmo ti risparmia una chiamata al metodo (risparmi un salto nello stack) senza perderne in prestazioni allora conviene condensare.

    Tutto, comunque, dipende dalla mole di lavoro effettuata per stabilire la relazione di uguaglianza, minoranza o maggioranza. Il caso più classico è quello del confronto numerico. Le seguenti due classi sono perfettamente equivalenti ed entrambe consisistenti con equals(), ma la seconda è decisamente più semplice da implementare, capire e manutenere.

    codice:
    // Esempio 1
    public class Oggetto {
       private int x;
       public Oggetto(int x) { this.x = x; }
       public int getX() { return x; }
       public void setX(int x) { this.x = x; }
       public boolean equals(Object obj) {
          Oggetto o = (Oggetto) obj;
          return (x == o.getX());
       }
       public int compareTo(Object obj) {
          Oggetto o = (Oggetto) obj;
          int y = o.getX();
          return (x < y) ? -1 : (equals(o) ? 0 : 1);
       }
    }
    
    // Esempio 2
    public class Oggetto {
       private int x;
       public Oggetto(int x) { this.x = x; }
       public int getX() { return x; }
       public void setX(int x) { this.x = x; }
       public boolean equals(Object obj) {
          Oggetto o = (Oggetto) obj;
          return (x == o.getX());
       }
       public int compareTo(Object obj) {
          Oggetto o = (Oggetto) obj;
          return (x - o.getX());
       }
    }
    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

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 © 2025 vBulletin Solutions, Inc. All rights reserved.