Visualizzazione dei risultati da 1 a 10 su 13

Hybrid View

  1. #1
    Utente di HTML.it
    Registrato dal
    Oct 2014
    Messaggi
    315
    Quote Originariamente inviata da andbin Visualizza il messaggio
    Perché c'è molto "dietro" le lambda expression e method reference! E il compilatore effettua un bel po' di cose di nascosto.

    Tieni presente che Java non è un linguaggio "funzionale". E non lo è ancora adesso, in senso stretto, nemmeno con Java 8. Nei linguaggi funzionali la "funzione" è un tipo di prima classe, che può essere passato, ritornato, assegnato alla stregua di altri tipi di dati.
    In Java no, non è così, almeno per il momento. Per introdurre lambda expression/method reference nel linguaggio hanno dovuto fare delle scelte, importanti e sicuramente non banali, più che altro per allinearsi a quello che è il type-system attuale di Java, fatto solo di primitivi e classi/interfacce(/enum/annotazioni, e anche array) e basta. Per farlo hanno tirato fuori innanzitutto il concetto di "interfaccia funzionale".
    Quando tu passi ad un metodo l'espressione TestCitta::getCitta, non stai passando (per ora, almeno in Java 8) un riferimento a getCitta! Sotto-sotto viene creato un oggetto che implementa la interfaccia indicata nel parametro, che deve avere il singolo metodo astratto che corrisponde, come forma, al tuo getCitta.
    Grazie per la spiegazione.

    Quote Originariamente inviata da andbin Visualizza il messaggio
    Se vuoi andare molto a fondo in queste cose, allora es.:
    - Maurice Naftalin's Lambda FAQ
    - Java 8 Lambdas - A Peek Under the Hood
    - Java 8: The First Taste of Lambdas

    E questi comunque sono aspetti parecchio "avanzati" ....
    sono aspetti un tantino avanzati e per il momento vorrei tralasciarli però grazie per i link.

    Quote Originariamente inviata da andbin Visualizza il messaggio
    In informatica (ma anche in logica matematica se non sbaglio) un "predicato" è una funzione che dato un valore X restituisce un booleano vero/falso. E l'uso più ovvio e naturale è per realizzare dei filtri al fine di accettare/rifiutare i valori.


    Detto così, si ok è corretto.

    Cerca anche di vedere la questione dell'inferenza dei tipi:

    - il parametro è Predicate<Citta>
    - Predicate ha un metodo astratto boolean test(T t) (questo è il metodo "funzionale")
    - quindi la firma da implementare è boolean test(Citta)
    - passi un "riferimento" (come descritto prima) ad un metodo public static boolean getCitta(Citta)

    Come vedi (parti in rosso) la forma corrisponde, quindi per il compilatore è ok.
    Il concetto vale per Predicate e per tutte le altre intefacce "funzionali".
    Ah ecco, quindi è un discorso valido per tutte le interfacce funzionali. Per certi versi potrei seguire quindi questo "schema" per chiarirmi le idee non solo su Predicate.

    Tornando all'esercizio devo stampare la lista delle città di mare. Questo è il codice:
    codice:
    public static void main(String args[]) {
    ...
            System.out.println("Lista città di mare:\n"+ getCittaFiltrate(listaCitta, TestCitta::mare) + "\n");
    }    
    
    public static List<Citta> getCittaFiltrate(List<Citta> listaCitta, Predicate<Citta> p) {
            final Iterator<Citta> i = listaCitta.iterator();
            while(i.hasNext()) {            
                Citta citta = i.next();
                if(!p.test(citta)) {
                    i.remove();
                }
            }
            return listaCitta;
    }
        
    public static boolean mare(Citta citta) {
            return "true".equals(citta.isDiMare());
    }
    Il problema è che stampa sempre una lista vuota perchè anche nel momento in cui va a selezionare una città di mare (es. Bari e Venezia) non riconosce "true" ma "false" e quindi viene lanciato remove() che rimuove l'elemento selezionato dall'iteratore.
    Non vorrei che sia un altro errore stupido che non riesco a correggere.
    Ultima modifica di newutente; 30-12-2014 a 20:28

  2. #2
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,284
    Quote Originariamente inviata da newutente Visualizza il messaggio
    codice:
    public static boolean mare(Citta citta) {
            return "true".equals(citta.isDiMare());
    }

    Non vorrei che sia un altro errore stupido che non riesco a correggere.
    Ehm ... purtroppo sì, invece. "true" è un String è il equals è il suo, di String. Ma stai passando come argomento un Boolean (autoboxato da boolean). Il equals riceve in generale un Object ma è tipico per le classi verificare che l'oggetto sia dello stesso tipo (tipicamente con instanceof). E String quindi non accetta un Boolean!

    Banalmente si potrebbe fare

    return citta.isDiMare() == true;

    o ancora più semplice:

    return citta.isDiMare();

    che non cambia nulla nel significato.


    Ma c'è di più. Tu hai creato un metodo statico che riceve un Citta e su quest'ultimo invochi un metodo di istanza isDiMare(). Di per sé non servirebbe ... bastarebbe invocare

    System.out.println("Lista città di mare:\n"+ getCittaFiltrate(listaCitta, Citta::isDiMare) + "\n");
    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
    Oct 2014
    Messaggi
    315
    Quote Originariamente inviata da andbin Visualizza il messaggio
    Ehm ... purtroppo sì, invece. "true" è un String è il equals è il suo, di String. Ma stai passando come argomento un Boolean (autoboxato da boolean). Il equals riceve in generale un Object ma è tipico per le classi verificare che l'oggetto sia dello stesso tipo (tipicamente con instanceof). E String quindi non accetta un Boolean!

    Banalmente si potrebbe fare

    return citta.isDiMare() == true;

    o ancora più semplice:

    return citta.isDiMare();

    che non cambia nulla nel significato.
    accidenti che errore. grazie per avermelo fatto notare.

    Quote Originariamente inviata da andbin Visualizza il messaggio
    Ma c'è di più. Tu hai creato un metodo statico che riceve un Citta e su quest'ultimo invochi un metodo di istanza isDiMare(). Di per sé non servirebbe ... bastarebbe invocare

    System.out.println("Lista città di mare:\n"+ getCittaFiltrate(listaCitta, Citta::isDiMare) + "\n");
    e questo posso farlo perchè il metodo isDiMare restituisce un boolean e quindi è "compatibile" con Predicate?

  4. #4
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,284
    Quote Originariamente inviata da newutente Visualizza il messaggio
    e questo posso farlo perchè il metodo isDiMare restituisce un boolean e quindi è "compatibile" con Predicate?
    Per i metodi (non conto ora la forma per i costruttori) i method reference possono avere in generale tre forme:

    object::instanceMethod
    Class::staticMethod
    Class::instanceMethod

    I primi due casi sono equivalenti ad avere una lambda expression che ha tanti parametri quanti sono quelli del metodo.
    Es.

    Math::max è equivalente ad una lambda expression (a, b) -> Math.max(a, b)

    Perché il metodo max ha due parametri (ci sono 4 versioni in overload, con tipi differenti ... quale verrebbe scelto dipende ovviamente dal contesto e dalla inferenza dei tipi).

    Mentre il terzo caso è equivalente ad una lambda expression in cui il primo parametro è il "target" del metodo referenziato.
    Es.

    Citta::isDiMare è equivalente alla lambda expression (c) -> c.isDiMare()

    E quest'ultima corrisponde al boolean test(Citta) di Predicate<Citta> perché riceve un parametro (Citta per inferenza) e l'espressione c.isDiMare() dà un boolean.
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    java.util.function Interfaces Cheat SheetJava Versions Cheat Sheet

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.