Visualizzazione dei risultati da 1 a 4 su 4
  1. #1
    Utente di HTML.it
    Registrato dal
    Sep 2010
    Messaggi
    2

    [Java] Ordinamento di Vettori di oggetti - Comparable e Comparator

    Colgo l'occasione per fare un saluto a tutto il forum visto che questo è il mio primo post; ma veniamo al dunque.

    Sono uno studente di informatica alle prime armi e al momento mi trovo ad arrancare su un argomento che credo dovrei invece padroneggiare in quanto scheletro di molti programmi: l'ordinamento.


    Per ordinare array di interi o di stringhe non dovrei aver problemi in quanto ci è stata fornita una classe apposita con tutta una serie di metodi per eseguire facilmente i vari tipi di ordinamento; ma quando si è parlato di ordinare dei vector contenenti oggetti, sono cominciati i problemi.

    Un vecchio topic su questo forum illustrava come utilizzare il metodo comparable.
    Ad esempio: avendo un vector contenente un array di oggetti di tipo FileInfo
    codice:
    public class FileInfo implements Comparable {
        private String directory;
    
        private String nome;
    
        private long dimensione;
    
        public FileInfo(String directory, String nome, long dimensione) {
            this.directory = directory;
            this.nome = nome;
            this.dimensione = dimensione;
    e volendo ordinarlo secondo directory+nome, dovevo aggiungere, al fondo della classe, il metodo compareTo
    codice:
    public int compareTo(Object obj) throws ClassCastException {
            FileInfo p = (FileInfo)obj;
            int confrontoDirectory = directory.compareTo(p.directory);
            if(confrontoDirectory != 0) {
                return confrontoDirectory;
            }
            return nome.compareTo(p.nome);
        }
    Per poi utilizzare semplicemente nel programma principale il metodo Collections.sort(v) [dove v è il nome del vettore da ordinare].

    Il problema arriva nel momento in cui vorrei dare all'utente la possibilità di scegliere in che modo ordinare il Vector in questione.
    In questo caso dovrei poter scegliere tra directory, directory+nome, dimensione; sempre in un vecchio topic di questo forum mi pareva di aver visto una discussione che riguardava un simile argomento affermando che, in questo caso, sarebbe stato necessario utilizzare Comparator al posto di Comparable ma non avendo capito molto di quel thread, mi ritrovo a chiedere a voi come si potrebbe fare.


    Inoltre mi chiedevo, nel caso volessi implementare un metodo per cercare un file per nome (restituendo un vettore con tutti file trovati, considerando che un file con lo stesso nome puo' essere trovato in directory differenti), se ci fosse qualche scorciatoia per eseguire una ricerca binaria (la più efficiente una volta ordinato il vettore) su di un vector di tipo FileInfo (vedi sopra).

    Un grazie in anticipo a chiunque mi possa aiutare ^_^

  2. #2
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,284

    Re: [Java] Ordinamento di Vettori di oggetti - Comparable e Comparator

    Originariamente inviato da Marcows
    affermando che, in questo caso, sarebbe stato necessario utilizzare Comparator al posto di Comparable ma non avendo capito molto di quel thread, mi ritrovo a chiedere a voi come si potrebbe fare.
    Come hai ben visto e fatto, Comparable va implementato nella classe degli oggetti da comparare. Pertanto di Comparable per un certo tipo ce n'è solo 1. L'ordinamento fornito da Comparable dovrebbe essere (e si definisce come) il "natural ordering", ovvero l'ordine più "naturale" che ha senso per un certo tipo di oggetti (es. per una classe Persona che ha nome/cognome l'ordinamento più "naturale" è per cognome poi per nome).

    E se vuoi definire altri diversi criteri di ordinamento si può implementare Comparator in altre classi slegate da quella degli oggetti. L'unica differenza è tecnica nei metodi.

    Comparable ha compareTo() che riceve 1 oggetto che va comparato con il 'this' (perché appunto è nella classe degli oggetti). mentre Comparator ha compare() che riceve 2 oggetti, perché la classe è slegata da quella degli oggetti comparati.

    Ma alla fin fine è tutto qui, se hai già capito come implementare Comparable (e mi pare di sì visto il tuo codice), implementare Comparator in una classe separata è comunque immediato.
    E per usarla invece di fare:

    Collections.sort(v);

    fai

    Collections.sort(v, new TuoAltroComparatore());

    P.S. dichiarare il throws ClassCastException è del tutto inutile/superfluo.

    Originariamente inviato da Marcows
    Inoltre mi chiedevo, nel caso volessi implementare un metodo per cercare un file per nome (restituendo un vettore con tutti file trovati, considerando che un file con lo stesso nome puo' essere trovato in directory differenti), se ci fosse qualche scorciatoia per eseguire una ricerca binaria (la più efficiente una volta ordinato il vettore) su di un vector di tipo FileInfo (vedi sopra).
    Collections ha anche i binarySearch() per cercare con la tecnica della ricerca "binaria", a patto ovviamente che la lista sia già ordinata.

    E se è stata ordinata in base a Comparable dovrai usare il binarySearch che si basa su Comparable mentre se è stata ordinata in base ad un XyzTuoAltroComparatore, dovrai usare l'altro binarySearch a cui passare lo stesso comparatore. Perché è chiaro che la ricerca binaria deve "seguire" lo stesso criterio di ordinamento!
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    java.util.function Interfaces Cheat SheetJava Versions Cheat Sheet

  3. #3
    Utente di HTML.it
    Registrato dal
    Sep 2010
    Messaggi
    2
    Quindi Comparator posso implementarlo in qualsiasi classe? E quindi per dare all'utente la possibilità di scegliere secondo quale criterio ordinare il Vector dovrei creare (in una classe) un metodo diverso per ogni criterio di confronto giusto?

    Ad esempio potrei implementare la seguente classe:
    codice:
    class Comparator implements Comparator{
    
        public int compareDim(Object dim1, Object dim2){
    
            Int dim1Lung = ( (FileInfo) dim1 ).getDimensione();
            Int dim2Lung = ( (FileInfo) dim2 ).getDimensione();
    
            return dim1Lung.compareTo(dim2Lung);
    
        }
        
        public int compareDir (Object dir1, Object dir2){
            
            String dir1alf = ( (FileInfo) dir1 ).getDirectory();
            String dir2alf = ( (FileInfo) dir2 ).getDirectory();
            
            return dir1alf.compareTo(dir2alf);
        }
        
        public int compareDirNom (Object dirNom1, Object dirNom2){
            
            String dir1 = ( (FileInfo) dirNom1 ).getDirectory();
            String dir2 = ( (FileInfo) dirNom2 ).getDirectoy();
            int confrontaDirectory = dir1.compareTo(dir2);
            if (confrontaDirectory != 0){
                return confrontaDirectory;
            }
            
            String nom1 = ( (FileInfo) diNom1 ).getNome();
            String nom2 = ( (FileInfo) diNom2 ).getNome();
            return nom1.compareTo(nom2);
        }
    }
    E per ordinare gli elementi in base a directory+nome, nella classe dove mi serve, dovrei inserire questo codice?
    codice:
    Collections.sort(v, new Comparator.compareDirNom() );
    E, giusto per concludere, se volessi ricercare il file di nome ELEM, dovrei inserire questo codice (ovviamente creando il metodo compareNom nella mia classe Comparator) giusto ?
    codice:
    Collections.sort(v, new Comparator.compareNom() );
    Collections.binarySearch(v, ELEM)
    In questo modo mi riporterebbe l'indice (integer) di "v" in cui ha trovato un FileInfo il cui campo Nome sia uguale ad ELEM.....ma ipotizzando che esistano 3 file ELEM in 3 diverse cartelle e che io voglia sapere la posizione non del primo che trova ma di ognuno di essi, come dovrei fare?

  4. #4
    Utente di HTML.it L'avatar di bstefano79
    Registrato dal
    Feb 2004
    Messaggi
    2,520
    no devi creare 3 comparatori diversi che implementa comparetor

    codice:
    class CompareDim implements Comparator{
    
        public int compare(Object dim1, Object dim2){
    
            Int dim1Lung = ( (FileInfo) dim1 ).getDimensione();
            Int dim2Lung = ( (FileInfo) dim2 ).getDimensione();
    
            return dim1Lung.compareTo(dim2Lung);
    
        }
    }
    
    
    class CompareDir implements Comparator{
     public int compare(Object dir1, Object dir2){
            
            String dir1alf = ( (FileInfo) dir1 ).getDirectory();
            String dir2alf = ( (FileInfo) dir2 ).getDirectory();
            
            return dir1alf.compareTo(dir2alf);
        }
    }
    
     class CompareDirNom implements Comparator{
       public int compare(Object dirNom1, Object dirNom2){
            
            String dir1 = ( (FileInfo) dirNom1 ).getDirectory();
            String dir2 = ( (FileInfo) dirNom2 ).getDirectoy();
            int confrontaDirectory = dir1.compareTo(dir2);
            if (confrontaDirectory != 0){
                return confrontaDirectory;
            }
            
            String nom1 = ( (FileInfo) diNom1 ).getNome();
            String nom2 = ( (FileInfo) diNom2 ).getNome();
            return nom1.compareTo(nom2);
        }
    }
    e poi usare quello che ti serve

    codice:
    Collections.sort(v, new CompareDirNom() );

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.