Visualizzazione dei risultati da 1 a 10 su 10

Discussione: Metodi Generici

  1. #1
    Utente di HTML.it
    Registrato dal
    Jun 2009
    Messaggi
    24

    Metodi Generici

    Ciao a tutti, devo scrivere un metodo generico che preso in input un array ritorna i valori min e max, probabilmente mi manca una nozione fondamentale riguardo ai tipi generici, quindi per ora evito di impiastrare tutto con il codice, ma in pratica il mio problema è che in questa funzione, quando faccio il controllo sulla variabile
    T min > a[i]
    mi dice che non posso utilizzare gli operatori di confronto sui tipi generici, cosa che a livello logico capisco benissimo, ma allora come posso fare dei confronti all'interno di tipi/metodi generici?

    grazie in anticipo

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

    Re: Metodi Generici

    Originariamente inviato da anearion
    T min > a[i]
    mi dice che non posso utilizzare gli operatori di confronto sui tipi generici
    Innanzitutto i generics hanno a che fare solo con i tipi "reference", non tipi primitivi. E per i tipi reference gli operatori < <= > >= non funzionano affatto (è un errore).

    Se vuoi confrontare oggetti ti devi basare su Comparable o un Comparator esplicito. (guarda i min()/max() di java.util.Collections, vedrai che entrambi sono in 2 versioni).
    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
    Jun 2009
    Messaggi
    24
    grazie And, anche se le collezioni sono nel capitolo dopo nelle dispense, quindi non capisco il prof. come vuole che facciamo l'esercizio...
    Comunque mi sono un pò arrangiato ed ora il metodo funziona, anche se sinceramente è tutto fuorchè generico dato che ho dovuto fare diversi casting per farlo andare senza errori.
    Praticamente ora mi opera solamente coi i tipi Integers, però non sono per niente soddisfatto dato che se volessi passargli un array di String non funzionerebbe na ceppa, non esiste un modo alternativo ai comparable od i comparator ?
    Per spiegarmi meglio incollo il codice, omettendo le parti che non riguardano questo problema.

    questa è la classe dove sta il metodo in questione:

    codice:
    package point; 
    public class Pair<T> { 
        private T primo, secondo; 
        public Pair(T primo, T secondo){ 
            this.primo = primo; 
            this.secondo = secondo; 
        } 
        public void setPrimo(T x){ primo = x; } 
        public void setSecondo(T x){ secondo = x; } 
        public T getPrimo(){ return primo; } 
        public T getSecondo(){ return secondo; } 
        public Pair<T> copySwap(Pair<T> p){...} 
        public Pair<T> MinMax(T[] a){ 
            T min = a[0]; 
            for(int i = 0; i < a.length; i++){ 
                if((Integer)min > (Integer)a[i]) { 
                    min = a[i]; 
                } 
           } 
           T max = a[0]; 
           for(int i = 0; i < a.length; i++){ 
               if((Integer)max < (Integer)a[i]) { 
                   max = a[i]; 
               } 
           } 
           Pair p = new Pair(0,0); 
           p.setPrimo(min); 
           p.setSecondo(max); 
           return p; 
           } 
    }


    questo è il main dove testo il metodo:

    codice:
    package point; public class Main { public static void main(String[] args){ 
        Integer[]a = {2, 5, 6, 9, 1, 4, 11 }; 
        Pair<Integer> p = new Pair<Integer> ( 0, 0); 
        p = p.MinMax(a);
        System.out.println(p.getPrimo()+"\n"+p.getSecondo()); 
        } 
    }
    Cioè il fatto che io debba dichiarare l'array di Integer unito al fatto che faccio un casting per operare sugli Integer mi rende inutile la "genericità" del metodo...

    EDIT: mhh, ma non mi ha importatato l'indentazione perchè ho fatto un copi&incolla direttamente da NetBeans ?

  4. #4
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,284
    Originariamente inviato da anearion
    non esiste un modo alternativo ai comparable od i comparator ?
    La questione è che nessuno ti vieterebbe di dettare delle specifiche per un "contratto" che deve esistere tra gli oggetti e il tuo metodo minmax ..... ma visto che esistono già Comparable/Comparator ... perché inventarsi qualcos'altro??

    Comunque il tuo metodo MinMax innanzitutto dovrebbe essere static, visto che come è adesso (di istanza) lo invochi su un oggetto ma non usi di certo il suo "stato".
    Inoltre, in ogni caso non è quello che si chiama metodo "generico". Un metodo che si dice davvero "generico" è un metodo che dichiara uno (o più) type variable tramite la sintassi <...qualcosa...>

    I cast a Integer ovviamente non vanno bene, fissano un tipo. Ripeto che devi basarti su Comparable o un Comparator esplicito.
    E la gestione finale di quel Pair non è comunque nemmeno "generica".
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    java.util.function Interfaces Cheat SheetJava Versions Cheat Sheet

  5. #5
    eccoti un esempio

    codice:
    import java.util.*;
    /**Progettp d'esempio nella ricerca del valore max e del min su un vettore di interi preso in input
     * @autor Naruto 92
     */
    public class MaxEMinVettori
    {
        /**
         * Ritorna il valore max di un array preso in input
         * @return il valore max
         * @param array l'array da scansionare alla ricerca del max
         */
        private Object max(Integer[] array){
            return Collections.max(Arrays.asList(array));
        }
        /**
         * Ritorna il valore min di un array preso in input
         * @return il valore min
         * @param array l'array da scansionare alla ricerca del min
         */
        private Object min(Integer[] array){
            return Collections.min(Arrays.asList(array));
        }
        /**
         * Avvio del programma
         * @param argv array di stringhe passato in automatico dall'OS
         */
        public static void main(String argv[]){
            MaxEMinVettori mm=new MaxEMinVettori();
            Integer[] array={1, 2, 3, 4, 5};
            System.out.println("Stampiamo l'array!");
            System.out.println(Arrays.toString(array));
            System.out.print("Stampiamo il valore max: ");
            System.out.println(mm.max(array));    
            System.out.print("Stampiamo il valore min: ");
            System.out.println(mm.min(array)); 
        }
    }
    I miei esempi in Java qui: http://cdpjavaexamples.altervista.org/index.html

  6. #6
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,284
    Originariamente inviato da Naruto 92
    codice:
        private Object max(Integer[] array){
            return Collections.max(Arrays.asList(array));
        }
    
        private Object min(Integer[] array){
            return Collections.min(Arrays.asList(array));
        }
    Innanzitutto qui non c'è nulla di "generico" e poi comunque se si trattasse di invocare banalmente min/max di Collections, sarebbe capace di farlo pure mia sorella.

    Questo qui sotto è un esempio di min() davvero "generico".

    codice:
    public class ProvaMin {
        public static void main(String[] args) {
            String[] str = { "pippo", "prova", "ciao", "hello" };
    
            String s = min(str);
            System.out.println(s);
        }
    
        public static <T extends Comparable<? super T>> T min(T[] arr) {
            T min = arr[0];
    
            for (int i = 1; i < arr.length; i++) {
                if (arr[i].compareTo(min) < 0) {    // Se arr[i] minore di min
                    min = arr[i];
                }
            }
    
            return min;
        }
    }
    Il min() di Collections a parte ovviamente il fatto di agire su una Collection è dichiarato leggermente diverso per quanto riguarda la type variable, ma per una questione di compatibilità all'indietro che ora non sto a spiegare (centra la erasure).
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    java.util.function Interfaces Cheat SheetJava Versions Cheat Sheet

  7. #7
    Utente di HTML.it
    Registrato dal
    Jun 2009
    Messaggi
    24
    Originariamente inviato da andbin
    codice:
    public static <T extends Comparable<? super T>> T min(T[] arr) {
    Scusa la mia ignoranza, ma non capisco troppo bene la linea quotata, praticamente "T extends Comparable" indica un metodo generico che estende Comparable, ma "<? super T>" indica che un tipo qualsiasi ( a questo serve il wildcard giusto ) è supertipo di T ? fai conto che se è cosi non capisco a che serve.
    Inoltre "T min" non ho idea di perchè stia li, il tipo di ritorno non è tutto quello prima ?
    Capisco che potrebbe essere una scemata, ma fai conto che non ho mai visto ( per ora ) un metodo dichiarato in questo modo :P

    Grazie in anticipo

  8. #8
    Originariamente inviato da andbin
    Innanzitutto qui non c'è nulla di "generico" e poi comunque se si trattasse di invocare banalmente min/max di Collections, sarebbe capace di farlo pure mia sorella.
    infatti non è generico.
    nell'esempio che anearion ha postato sopra usa degli Integer e quindi l'esempio è ispirato a tale
    I miei esempi in Java qui: http://cdpjavaexamples.altervista.org/index.html

  9. #9
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,284
    Originariamente inviato da anearion
    Scusa la mia ignoranza, ma non capisco troppo bene la linea quotata, praticamente "T extends Comparable" indica un metodo generico che estende Comparable, ma "<? super T>" indica che un tipo qualsiasi ( a questo serve il wildcard giusto ) è supertipo di T ? fai conto che se è cosi non capisco a che serve.
    In effetti se non hai mai visto una cosa del genere, ti può sembrare "strana" e contorta. Ma per ognuna delle cose indicate c'è un motivo ben preciso.

    La prima cosa che è evidente è "T extends Comparable". Su questo credo non ci siano dubbi. Il tipo trattabile dal metodo può essere qualunque, purché sia Comparable. E questo viene controllato strettamente in fase di compilazione.

    String implementa Comparable, se passo un String[], tutto ok (come appunto nel mio esempio). Se invece avessi un array:

    Object[] arr = { "aaa" .... };

    l'array è tecnicamente ok ma il tipo visto dal compilatore è ovviamente Object[] e Object non implementa Comparable. Quindi al mio min() non lo puoi passare.

    Si potrebbe accettare anche Object o altro spostando il controllo non più in fase di compilazione ma a runtime. Si potrebbe togliere l'extends Comparable e nel metodo fare un cast degli oggetti a Comparable .... ma se fallisce, beh, accade a runtime. È la scelta che uno può fare ....

    Vediamo invece il <? super T> che è più interessante. Ma facciamo un passo indietro. Avrei potuto dichiarare più semplicemente:

    ... <T extends Comparable<T>> ...

    Tecnicamente ok, ma sarebbe troppo "stretto". Per capire la questione in questi casi si fa un esempio con la ereditarietà. Un esempio classico: classe Frutto e poi 2 sottoclassi Mela e Arancia.

    Se fossero:

    class Frutto { ... }
    class Mela extends Frutto implements Comparable<Mela> { ... }
    class Arancia extends Frutto implements Comparable<Arancia> { ... }

    Mela è comparabile solo con altri Mela, idem Arancia solo con altri Arancia. In questo caso la forma <T extends Comparable<T>> lo accetterebbe perfettamente.

    Mettiamo che T è Mela, quindi Comparable<T> diventa Comparable<Mela> che infatti è proprio così per Mela! Quindi tutto corretto.

    Ora spostiamo la implementazione di Comparable. Supponiamo che sia in Frutto, perché la comparazione si basa su un campo "comune" in Frutto:

    class Frutto implements Comparable<Frutto> { ... }
    class Mela extends Frutto { ... }
    class Arancia extends Frutto { ... }

    Ora <T extends Comparable<T>> non può più corrispondere!! Perché Mela è sì Comparable ma è Comparable<Frutto> e quindi non è più vero che T è Comparable<T>.

    Ecco perché si mette Comparable<? super T>. È più "ampia". Il concetto è che qui non interessa tanto se Mela è Comparable<Mela> o Comparable<UnSuperTipo> ... ma basta ed è sufficiente che sia Comparable!!

    Originariamente inviato da anearion
    Inoltre "T min" non ho idea di perchè stia li, il tipo di ritorno non è tutto quello prima ?
    No, per i metodi "generici" stando alle regole di Java: prima i "modificatori" se ce ne sono (tecnicamente in qualunque ordine ma c'è un ordine "consigliato" es. public static final), poi < ... > per dichiarare la/e type variable, poi il tipo di ritorno, poi il nome del metodo seguito da ( ...parametri... ).
    Tutto qui.

    Lo spiega formalmente qui.
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    java.util.function Interfaces Cheat SheetJava Versions Cheat Sheet

  10. #10
    Utente di HTML.it
    Registrato dal
    Jun 2009
    Messaggi
    24
    grazie mille and, sei meglio di qualsiasi professore/dispensa
    grazie anche a naruto 92, comunque sia il tuo esempio mi ha chiarito le idee.

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