SlideShare ist ein Scribd-Unternehmen logo
1 von 62
Introduzione a Java
Valerio Radice
Valerio Radice
valerio.radice@nextre.it
WEB DEVELOPER & TEACHER
https://github.com/valix85
https://plus.google.com/+ValerioRadice85
https://it.linkedin.com/in/valix85/it
Di cosa si parlerà ?
 Invocazione virtuale dei metodi
 Eccezioni, gestione e creazione
 Catturare e rilanciare eccezioni
 NullPointer
 Operazioni lambda, Predicate e principali operazioni
 Stream
Invocazione virtuale dei metodi
Un'invocazione a un metodo m può definirsi virtuale quando m è definito in una classe
A, ridefinito nella sottoclasse B(override) e invocato su un'instanza di B tramite una
reference di A(polimorfismo per dati). Il compilatore pensa di avviare il metodo m di
A(virtualmente) ma in realtà viene invocato il metodo m della classe B!
Quello che avviene è che il metodo m di B ha sovrascritto lo stesso intervallo di
puntamento che usa A
Giocatore g4 = new GiocatoreArcade("Pong");
System.out.println(g4.toString());
Giocatore Creato
GiocatoreArcade{punteggio=0, nominativo='Bipede da sala giochi', id=12012, gioco='Pong'}
Eccezione
Situazione imprevista che può presentarsi durante il flusso di un'applicazione.
Alcune eccezioni possono essere catturate per gestire una risposta del sistema
evitando un errore fatale che ne comprometta l'esecuzione.
Vengono implementate dalla sottoclasse Exception di Throwable.
public static void main(String[] args) {
int x = 3;
int y = 0;
int ris = x/y;
}
Eccezioni
Eccezioni
public static void main(String[] args) {
int x = 3;
int y = 0;
try{
int ris = x/y;
}catch(ArithmeticException e){
System.out.println("DivBy 0! exception");
}
}
try - catch
Le eccezioni oltre che ad essere generate possono essere lanciate in situazioni
previste per poter reagire di conseguenza, possono essere create e manipolate.
I casi di eccezione possono essere gestiti in blocchi di codice di tipo try – catch.
All'interno del blocco try si inserisce il blocco di codice che potrebbe sollevare
un'eccezione, mentre i blocchi catch catturano una o più eccezioni, dalla meno
generica alla più generica (Exception).
I comandi per gestire le eccezioni sono: try , catch , finally , throw e throws
try
Nel blocco try si inserisce del codice che potrebbe sollevare eccezioni,
solitamente al fine di una gestione più lineare si consiglia di effettuare la
dichiarazione al di fuori e l'assegnamento al suo interno.
Qualsiasi istruzione, all'interno del blocco try, eseguita dopo quella che solleva
l'eccezione NON sarà raggiunta se l'eccezione sarà sollevata.
try{
int ris = x/y;
System.out.println("Non stampo in caso di DivBy 0");
}
catch
I blocchi di catch servono per catturare una o più eccezioni, anche qui vale
l'ereditarietà, se catturo prima un'eccezione più generica non potrò catturare
dopo quella più specifica, il compilatore darà errore!
Si può eseguire un solo blocco di catch alla volta!
Dopo un blocco di catch il programma riprenderà da dopo il blocco try e non da
dopo l'istruzione che ha generato l'errore!
...
}catch(ArithmeticException e){
System.out.println("DivBy 0! exception");
}catch(Exception e){
//TODO...
}
e.printStackTrace()
Lo stack è la sequenza di metodi richiamati per eseguire un'operazione. Il metodo
e.printStackTrace() serve a stampare l'ordine delle chiamate (con informazioni
aggiuntive) richiamate a partire dalla riga che ha generato l'errore.
Sono presenti il nome del metodo, il nome del file e la riga in cui è avvenuta
l'eccezione, l'insieme dei metodi che hanno portato all'esecuzione di
quest'ultimo, e il tipo di di eccezione con il relativo message.
finally
Un blocco di codice finally è definito sempre dopo l'ultimo blocco di catch
dichiarato. Non può esistere un try senza catch o senza un finally, posso avere
un blocco try/catch oppure un blocco try/finally oppure un blocco
try/catch/finally.
}catch(Exception e){
//TODO...
}finally{
System.out.println("istruzioni sempre eseguite");
}
throw
Le eccezioni possono essere comandate, in casi particolari potrebbe essere
necessario lanciare delle eccezioni e lo si può fare all'interno di un blocco try
creando una nuova eccezione e lanciarla con la keyword throw. Attenzione tutto
il blocco di codice interessato dopo la dichiarazione del lancio di una nuova
eccezione sarà codice irraggiungibile e pertanto il compilatore darà errore.
try{
throw new NullPointerException("Messaggio opzionale");
//int ris = x/y;
//System.out.println("Non stampo in caso di DivBy 0");
}catch(NullPointerException ex) {
System.out.println(ex.getMessage());
}finally {
System.out.println("Messaggio sempre stampato");
}
throws
Gli errori che vengono sollevati volontariamente possono essere catturati e
gestiti subito, grazie a un blocco di catch, oppure possono essere rimandati al
metodo chiamante, delegando al chiamante come comportarsi in caso di errore.
Il chiamante dovrà quindi o inserire il metodo che potrebbe generare l'errore in
un blocco try/catch e quindi potrà scegliere come gestire l'eccezione oppure
potrà a sua volta rilanciarla a chi lo ha chiamato, così via fino al sistema
operativo della JVM che bloccherà il processo che causa l'eccezione
interrompendo l'esecuzione del programma.
public static void main(String[] args) throws NullPointerException {
Errore
L'errore è una situazione imprevista non dipendente da un errore commesso dallo
sviluppatore. Gli errori non sono gestibili!
Vengono implementati dalla sottoclasse Error di Throwable.
Gerarchia
Errori ed eccezioni possono essere
categorizzate in checked e
unchecked exception.
 Quelle in rosso
(RuntimeException e derivate)
sono situazioni non prevedibili
a priori, dipendono da eventi
esterni (input di utenti ecc..)
e sono dette UNCHECKED.
 Tutte le altre son prevedili e
controllabili, vengono
chiamate CHECKED.
Errore ed Eccezione
Non bisogna confondere errori ed eccezioni:
Errore = situazione / problema che un programma non può risolvere
Eccezione = problema non critico, gestibile e prevedibile.
Sia errore che eccezione vengono "lanciati" e sono entrambi figli della classe
Throwable. In caso di lancio di un'eccezione la JVM crea un'oggetto della classe
Throwable (o derivata) e crea un rapporto dettagliato (stacktrace) sull'accaduto,
interrompe il flusso per poi riprenderlo dopo il catch.
Posso catturare più eccezioni in un blocco catch dividendole con " | " (>=java7).
Un blocco finally verrà sempre eseguito per ultimo, anche dopo il catch, anche in caso
non ci siano catch (try finally) in caso di eccezione il finally viene eseguito e dopo il
programma terminerà in modo anomalo.
catch(ArithmeticException | EmptyStackException ex) {
try with resources (>=Java7)
 Meccanismo che permette la chiusura automatica degli oggetti che per essere usati
devono essere aperti (es: stream).
 Gli oggetti che devono essere istanziati e aperti sono tutti dichiarati nel blocco di
parentesi tonde tra il try e il suo statement.
 Tali oggetti non dovranno essere chiusi prima della fine del blocco try, ma è come
se i comandi di chiusura si trovassero automaticamente all'interno di un blocco
finally.
try with resources (>=Java7)
Se durante il try venisse sollevata un'eccezione essa verrebbe considerata come
prioritaria rispetto ad altre che potrebbero generarsi dalla chiusura degli oggetti
dichiarati dal blocco di reources.
Queste altre eccezioni verranno marcate come suppressed ma non verranno perse, ma
saranno accessibili come attributo dell'eccezione catturata col metodo
getSuppressed().
Gli oggetti utilizzabili dentro a un blocco resources devono obbligatoriamente
implementare l'interfaccia AutoCloseable o Closeable.
warnings
Non si tratta di veri e propri errori ma piuttosto di segnalazioni che alcuni
statement potrebbero portare, in altri contesti, a generare delle eccezioni che
non gestisco.
È possibile informare il compilatore per dirgli di ignorare uno o più warnings con
l'annotazione @SuppressWarning("nomeDelWarning") sulla classe che lo solleva.
@SuppressWarnings("serial")
throws e override
Quando si fa un override non è
possibile specificare clausole di
throws che non siano già
presenti in quello originale o
che non siano figlie della stessa
classe.
Devo sempre avere un
sottoinsieme delle eccezioni (o
al massimo uguali) a quelle del
padre. Il non dichiararla è un
sottoinsieme vuoto di quelle
del padre e quindi sempre
valido (ecco perché la
SottoClasseCorretta3 è
corretta!)
Eccezioni personalizzate
 Per generare una class Exception personalizzata è sufficiente estendere la
classe Exception (o una sua eccezione).
 È possibile, proprio come nelle classi, definire attributi e metodi
personalizzati.
 In particolare si può ridefinire il metodo getMessage() o altri metodi comuni,
istanziare un logger per loggare in automatico le eccezioni.
public class RandomException extends Exception {
RandomException(){
super("Random Exception generated");
}
@Override
public String toString() {
return getMessage() + " : numero sfortunato";
}
}
Assertion
Le asserzioni devono il loro successo alla progettazione per contratto, ovvero una
tecnica di programmazione per la quale si testa l'applicazione in tre
stati(asserzioni): precondizione, postcondizione e invarianti. Molto usata per
scrivere test.
Precondizione = sviluppatore asserisce a come deve trovarsi l'applicazione prima
di invocare un'operazione (non confondere con eccezione!)
Postcondizione = sviluppatore asserisce a come dovrà essere lo stato di
un'applicazione al termine dell'esecuzione di un'operazione. È un modo utile per
asserire a cosa fare ma non dice il come.
Invariante = serve a specificare vincoli su oggetti istanziati (consente stati di
inconsistenza temporanei, ma poi deve tornare consistente)
Asserzione
L'asserzione è invece una condizione di verità che deve sempre essere verificata. Essa
rappresenta uno strumento per testare la robustezza del software.
Le asserzioni possono essere abilitate in fase di sviluppo o test e disabilitate in fase di
produzione affinché il programma non subisca rallentamenti.
In caso di asserzione non verificata l'esecuzione verrà interrotta.
Per generare un'asserzione la si
dichiara con la keyword assert.
(lanciare la VM col parametro –ea )
(-ea è enableassertion)
int y = 0;
assert y!=0;
assert
 La parola chiave assert serve per asserire un valore di verità. Per poter
funzionare si deve avviare la JVM con il parametro –ea. Con -da si
disabilitano, ma basta avviarla senza parametri dato che di default sono
disabilitate.
 Con il comando -esa si abilitano le asserzioni anche nelle librerie di sistema.
 È possibile abilitare e disabilitare le asserzioni anche a livello di package
 Permette di definire un vincolo di verità che se non verificato genera un
errore
Interfaccia funzionale
Interfaccia che contiene un solo metodo ASTRATTO (detto anche SAM acronimo di
Simple Abstract Method).
Un'interfaccia è funzionale anche se ha altri metodi ma marcati come default con
un corpo proprio, l'importante è che sia UNO solo quello astratto.
Java8 ha un package con sole interfacce funzionali: java.lang.function
Un'interfaccia funzionale viene spesso implementata da una funzione lambda
Lambda
Un espressione lambda è detta anche funzione anonima (anonymous function),
non è un metodo appartenente ad una classe e chiamato tramite un oggetto, ma
una funzione senza nome definita al volo in maniera simile come le classi
anonime.
Solitamente si usa per implementare un'interfaccia funzionale al volo.
Classe anonima
Prima quando dovevamo implementare una classe anonima scrivevamo:
new Thread(new Runnable){
@Override public void run(){
System.out.println("di Java 8: Classe anonima ");
}
}).start();
Lambda
Grazie alle lambda possiamo dimezzare il codice rimuovendo la parte che può
dedurre tranquillamente il compilatore, possiamo avere una sintassi di questo
tipo:
ha la stessa valenza della classe anonima scritta precedentemente riducendo il
nostro codice da 5 linee a un'unica linea di codice.
new Thread(() -> System.out.println("Java 8: Funzione anonima")).start();
Espressione Lambda
L'espressione lambda può essere referenziata con una reference di un interfaccia
funzionale, e la sua definizione non è altro che l'implementazione dell'unico
metodo astratto dell'interfaccia funzionale, la nostra espressione lambda in
sostanza può sostituire un'interfaccia funzionale.
 Si concentra su cosa fare e non sul come farlo.
 Riduzione del codice
Espressione Lambda
Riduzione del codice
È possibile omettere parentesi tonde o graffe ove fossero necessarie per riuscire
a ridurre il tutto a una sola linea di codice, questo solo se la riga di codice
prevede una sola e unica istruzione, altrimenti bisognerà utilizzare le parentesi
dove ne necessitiamo.
Espressione Lambda: sintassi
parametro1 -> comando(parametro1)
(Tipo parametro1) -> comando(parametro1)
(parametro1,parametro2) -> {implementazione con return}
Il simbolo "->" serve a dividere i parametri (numero e tipo automaticamente
dedotti) dall'implementazione, che se monofunzione non richiede parentesi
graffe e NON vuole il return (errore di compilazione), in caso di più
funzioni/operazioni le graffe e il return diventano obbligatorie; anche return;
senza nulla è valido in caso di void.
Espressione Lambda: visibilità
All'interno di una classe anonima, il reference this si riferisce all'oggetto corrente
istanziato dalla classe anonima, e per riferirsi ai membri della classe che include
la classe anonima dobbiamo utilizzare una sintassi di questo genere:
NomeCasseEsterna.this.nomeMembro
con l'espressione lambda invece, il reference this si riferisce alla classe in cui è
inclusa l'espressione.
Vedi esempio seguente
Espressione Lambda: visibilità
public class LambdaThis{
private String stringa = "Variabile d'istanza di classe";
public void metodoContenenteLambda(){
String stringa = "variabile locale del metodo contenente";
new Thread(()-> System.out.println(this.stringa).start());
new Thread(()-> System.out.println(stringa).start());
}
public static void main(String[] args) {
LambdaThis lambdaThis = new LambdaThis();
lambdaThis.metodoContenenteLambda();
}
}
Espressione Lambda: visibilità
Per quanto riguarda le variabili locali dichiarati all'interno di un espressione
lambda, esse condivido lo stesso scope (visibilità) con il blocco di codice dove
sono definite.
Come le classi anonime anche le espressioni lambda possono utilizzare le variabili
esterne solo se sono state dichiarate final o sono effettivamente non
modificabili.
In molti casi il compilatore si accorge se tentiamo di modificare una variabile
dichiarata esternamente. Un trucco per “ingannare” il compilatore c'è, infatti
benché una variabile dichiarata final, e quindi non modificabile, possiamo
“wrappare” il valore della nostra variabile, modificando la struttura interna,
senza che crei problemi al compilatore.
Espressione Lambda: eccezioni
Quando utilizziamo le espressioni lambda bisogna fare attenzione alle eccezioni
cheked exception, ovvero eccezioni che NON sono sottoclassi di
RuntimeException.
Per sviare questo problema bisognerebbe usare il throws della dichiarazione del
metodo che potrebbe lanciare l'eccezione nel caso non siano gestite.
Purtroppo le lambda non dichiarano metodi, e non sarebbe possibile utilizzare la
clausola throws se non nel metodo dell'interfaccia funzionale che rappresentano.
Espressione Lambda: eccezioni
new Thread(() -> {
Thread.sleep(1000);
System.out.println("Hello World");
}).start();
questo tipo di codice darà luogo ad un errore di compilazione, e per risolverlo
abbiamo due possibilità:
 gestire tutto con il try –catch
 utilizzare un'interfaccia funzionale che definisca il metodo astratto con la
clausola throws richiesta
Espressione Lambda
L'obbiettivo delle espressioni lambda è il passaggio dinamico di algoritmi
implementati "al volo" come parametri di metodi.
Di fatto una lambda è la sola implementazione di un'interfaccia funzionale
quando necessario.
Espressione Lambda: referenza a
metodo statico
Un modo per implementare una lambda è l'utilizzo della chiamata ai metodi
statici (referenza a metodo).
 NomeClasse : : nomeDelMetodoStatico
Quando si ha un metodo statico che accetta un solo parametro il compilatore è in
grado di autodedurre tutte le informazioni necessarie (tipo e ordine).
public class Filtri{
public static boolean isFilmDiFantascienza(Film film){
return "Fantascienza".equals(film.getGenere());
}
}
...
Film[] filmDiFantascienza =
videoteca.getFilmFiltrati(Filtri::isFilmDiFantascienza);
Espressione Lambda: referenza a
metodo d'istanza
Stesso principio precedente applicato però non più su una classe ma su un'istanza
(oggetto) di essa.
 NomeOggetto : : nomeDelMetodoDIstanza
public class OridnamentoFilm {
public int ordinamentoPerNome(Film film, Film film1){
return film.getNome().compareTo(film1.getNome());
}
}
...
Film[] catalogo = videoteca.getFilm();
OrdinamentoFilm of1 = new OrdinamentoFilm();
...
Arrays.sort(catalogo, of1::ordinamentoPerNome);
Espressione Lambda: referenza a
metodo d'istanza di un certo tipo
Stesso principio dei precedente applicato però a un metodo non statico di una
classe senza però averne un'istanza.
 NomeClasse : : nomeDelMetodoDIstanza
Il metodo di istanza è un metodo non statico, ma richiamato attraverso la classe.
Collections.sort(myCollection, String::compareToIgnoreCase());
Espressione Lambda: referenza a
costruttore
In questo caso non ci si riferisce a un metodo statico in quanto il costruttore
rappresenta un'oggetto. Si otterrà un'istanza di quella classe. Mi permette di
evitare classe Factory.
 NomeClasse : : new
Package java.lang.function
"Functional interfaces provide target types for lambda expressions and
method references."
Interfaccia Predicate
 Un metodo astratto (è funzionale!) test()
 Accetta un predicato (confronto)
 Ritorna un booleano (Ottima per i test)
 Ideale per filtrare gli oggetti
 Possibilità di concatenare metodi: or(), xor(), e and()
Interfaccia Consumer
 Un metodo astratto (è funzionale!) accept()
 Accetta un predicato (confronto)
 Ritorna un void
 Utile a cambiare lo stato interno dell'oggetto passato / consumarlo
 Possibilità di concatenare metodi: andThen()
Interfaccia Supplier
 Un metodo astratto (è funzionale!) get()
 Ritorna un'istanza del tipo generico con la quale è dichiarata
 Utile a creare istanze / factory methods
Interfaccia Function
 Un metodo astratto (è funzionale!) apply()
 Permette di astrarre il concetto di funzione
 Utile a modificare il dato
Interfaccia Bi-Function
 Un metodo astratto (è funzionale!) apply()
 Permette di astrarre il concetto di funzione a due parametri
 Utile a modificare i dati, ritornando un solo dato
 Esistono anche Bi-Supplier e Bi-Predicate
Interfaccia Unary Operator
 Un metodo astratto (è funzionale!) apply(), ereditato da Function
 Permette di astrarre il concetto di trasformazione sul parametro
 Utile a trasformare un dato in ingresso
 Ritorna lo stesso tipo in ingresso
 Utile per combinare più espressioni lambda dello stesso tipo
Stream
 Lo Stream è una nuova interfaccia definita all'interno del package
java.util.stream
 rappresenta un flusso che ha come sorgente una collezione di dati, e sul quale
si possono eseguire operazioni, facendo utilizzo delle lambda e reference a
metodi
 Lo stream solitamente viene creato a partire da una determinata collezione,
tramite la chiamata del metodo stream().
Stream
È possibile istanziare uno stream passando un array al metodo statico of():
Stream <String> stringStream=Stream.of(arrayDiStringhe);
Passando all'altra versione del metodo of() direttamente dei valori:
Stream<String> stringStream=Stream.of(“Take”,“The”,“Time”);
Tramite il metodo statico generate() delle stessa classe Stream, ci fornisce uno stream
infinito perché ogni volta che vogliamo un valore dallo stream ne verrà creato uno:
Stream<Double> randomDouble=Stream.generate(Math.random);
Questo esempio di codice usando una reference al metodo random() della classe Math
restituisce un numero casuale di tipo double maggio o uguale di 0.0 e minore di 1.
Stream
È possibile iterare sulle collezioni utilizzando un' oggetto Stream, che definisce anche
un metodo forEach(), e da esso possiamo usufruire delle cosiddette “operazioni di
aggregazione” utilizzate in combinazione alle espressioni Lambda. È anche possibile
concatenare le operazioni per creare delle pipeline.
Lo stream non immagazzina elementi, ma permette di operare su di essi attraverso
una serie di operazioni: le pipeline
Smartphones
.stream()
.filters(s ->”Sasmsung”.equals(s.getMarca())
.forEach(s → Sout(s));
Pipeline
 Rappresenta un insieme di operazioni da eseguirsi su un flusso dati ( stream ).
 Le operazioni per creare ed usare una pipeline sono;
 Aprire una sorgete (ottenere uno stream)
 Eseguire zero o più operazioni di aggregazione / riduzione / intermedie
 Eseguire un metodo / operazione terminale per usare/raccogliere i dati modificati.
Esempio Pipeline
Pipeline: 3 componenti fondamentali
 Una sorgente: potrebbe essere una collezione o un array, o altri canali di
input/output, oppure il metodo generate() della classe Stream stessa, quindi per
ottenere un oggetto Stream la sorgente deve mettere a disposizione un metodo.
 Zero o più operazioni di aggregazione (o intermedie): queste tipi di operazione
hanno la caratteristica di ritornare un nuovo oggetto Stream, esempio il metodo
filter(). Altri tipi di metodi che abbiamo a disposizione sono map(), mapToDouble().
Questi e tanti altri metodi intermedi sono chiamati “metodi lazy(pigri)”, perché
vengo chiamati all'ultimo momento, ovvero saranno invocati solo quando sarà
invocato il metodo terminale, che ovviamente ha bisogno di metodi intermedi per
essere eseguito.
 Un' operazione terminale: metodo che restituisce un risultato che non è oggetto
Stream, ad es: Collect.
Optional
 Consente di evitare i NullPointerException nel caso in cui una pipeline non
ritorni nulla.
 Esistono OptionalDouble, OptionalLong, OptionalInt e Optional<T>
 Potrebbero sollevare NoSuchElementException
 Facilmente evitabile usando il metodo .orElse() che specifica cosa fare in caso
in cui l'optional sia vuoto
Optional: esempio
//double prezzoMedio = negozio
OptionalDouble prezzoMedio = negozio
.stream()
.filter(s->s.getMarca().equalsIgnoreCase("nokia"))
.mapToDouble(s->s.getPrezzo())
.average();
//.getAsDouble();
//System.out.println(prezzoMedio);
System.out.println(String.format("%.2f",prezzoMedio.orElse(0)));
Reduction Operation
 metodo che a partire dagli elementi di uno stream, ritorna un solo valore.
 Le tipiche implementazioni di operazione di riduzione sono min(), max(),
sum(), average(), count() ...
 Altre operazioni di riduzioni possono tornare delle collezioni, es reduce() e
collect()
Metodo Reduce
Esiste in più versioni (overload), la più famosa ha:
- Un oggetto detto identity che rappresenta il valore iniziale
- Un oggetto BinaryOperator (accumulator) che rappresenta un'espressione
lambda a due parametri
Il valore di reduce ritorna ad essere come il primo argomento della BiFunction.
Metodo Collect
Usato con i metodi statici della classe Collectors, anch'esso esiste in più versioni
(overload):
- Possiamo ottenere liste con Collectors.toList() (si duplicati)
- Possiamo ottenere dei Set (no duplicati)
- Consente operazioni di reducing(), groupingBy(), toList(), toCollection()

Weitere ähnliche Inhalte

Was ist angesagt?

Constructor and destructor in oop
Constructor and destructor in oop Constructor and destructor in oop
Constructor and destructor in oop Samad Qazi
 
Object Oriented with Java Programmazione Base
Object Oriented with Java Programmazione BaseObject Oriented with Java Programmazione Base
Object Oriented with Java Programmazione BaseFelice Pescatore
 
Introduzione ad angular 7/8
Introduzione ad angular 7/8Introduzione ad angular 7/8
Introduzione ad angular 7/8Valerio Radice
 
Java - Generic programming
Java - Generic programmingJava - Generic programming
Java - Generic programmingRiccardo Cardin
 
Grails object relational mapping: GORM
Grails object relational mapping: GORMGrails object relational mapping: GORM
Grails object relational mapping: GORMSaurabh Dixit
 
Java OOP s concepts and buzzwords
Java OOP s concepts and buzzwordsJava OOP s concepts and buzzwords
Java OOP s concepts and buzzwordsRaja Sekhar
 
PGDay UK 2016 -- Performace for queries with grouping
PGDay UK 2016 -- Performace for queries with groupingPGDay UK 2016 -- Performace for queries with grouping
PGDay UK 2016 -- Performace for queries with groupingAlexey Bashtanov
 
Iterator - a powerful but underappreciated design pattern
Iterator - a powerful but underappreciated design patternIterator - a powerful but underappreciated design pattern
Iterator - a powerful but underappreciated design patternNitin Bhide
 
Object and class relationships
Object and class relationshipsObject and class relationships
Object and class relationshipsPooja mittal
 
Introduction to Java -unit-1
Introduction to Java -unit-1Introduction to Java -unit-1
Introduction to Java -unit-1RubaNagarajan
 
Exception handling in java
Exception handling in javaException handling in java
Exception handling in javapooja kumari
 
Java ArrayList Tutorial | Edureka
Java ArrayList Tutorial | EdurekaJava ArrayList Tutorial | Edureka
Java ArrayList Tutorial | EdurekaEdureka!
 

Was ist angesagt? (20)

SQL select clause
SQL select clauseSQL select clause
SQL select clause
 
Class diagrams
Class diagramsClass diagrams
Class diagrams
 
Constructor and destructor in oop
Constructor and destructor in oop Constructor and destructor in oop
Constructor and destructor in oop
 
Object Oriented with Java Programmazione Base
Object Oriented with Java Programmazione BaseObject Oriented with Java Programmazione Base
Object Oriented with Java Programmazione Base
 
Introduzione ad angular 7/8
Introduzione ad angular 7/8Introduzione ad angular 7/8
Introduzione ad angular 7/8
 
16 virtual function
16 virtual function16 virtual function
16 virtual function
 
Java - Generic programming
Java - Generic programmingJava - Generic programming
Java - Generic programming
 
Inner classes in java
Inner classes in javaInner classes in java
Inner classes in java
 
Grails object relational mapping: GORM
Grails object relational mapping: GORMGrails object relational mapping: GORM
Grails object relational mapping: GORM
 
Java OOP s concepts and buzzwords
Java OOP s concepts and buzzwordsJava OOP s concepts and buzzwords
Java OOP s concepts and buzzwords
 
Exception Handling in Java
Exception Handling in JavaException Handling in Java
Exception Handling in Java
 
Html
HtmlHtml
Html
 
PGDay UK 2016 -- Performace for queries with grouping
PGDay UK 2016 -- Performace for queries with groupingPGDay UK 2016 -- Performace for queries with grouping
PGDay UK 2016 -- Performace for queries with grouping
 
Iterator - a powerful but underappreciated design pattern
Iterator - a powerful but underappreciated design patternIterator - a powerful but underappreciated design pattern
Iterator - a powerful but underappreciated design pattern
 
Object and class relationships
Object and class relationshipsObject and class relationships
Object and class relationships
 
Java reflection
Java reflectionJava reflection
Java reflection
 
Introduction to Java -unit-1
Introduction to Java -unit-1Introduction to Java -unit-1
Introduction to Java -unit-1
 
Exception handling in java
Exception handling in javaException handling in java
Exception handling in java
 
java token
java tokenjava token
java token
 
Java ArrayList Tutorial | Edureka
Java ArrayList Tutorial | EdurekaJava ArrayList Tutorial | Edureka
Java ArrayList Tutorial | Edureka
 

Ähnlich wie Java OCA teoria 5

Baby Steps TripServiceKata
Baby Steps TripServiceKataBaby Steps TripServiceKata
Baby Steps TripServiceKataAndrea Francia
 
Corso pratico di C# - 2013
Corso pratico di C# - 2013Corso pratico di C# - 2013
Corso pratico di C# - 2013Matteo Valoriani
 
Corso Programmazione Java Base
Corso Programmazione Java BaseCorso Programmazione Java Base
Corso Programmazione Java BaseK-Tech Formazione
 
Googletest, tdd e mock
Googletest, tdd e mockGoogletest, tdd e mock
Googletest, tdd e mockyuroller
 
Guida all'utilizzo di OpenFOAM su Windows10 (con Ubuntu LTS) - Capitolo 2
Guida all'utilizzo di OpenFOAM su Windows10 (con Ubuntu LTS) - Capitolo 2Guida all'utilizzo di OpenFOAM su Windows10 (con Ubuntu LTS) - Capitolo 2
Guida all'utilizzo di OpenFOAM su Windows10 (con Ubuntu LTS) - Capitolo 2Andrea Pisa
 
Java Unit Testing - JUnit (2)
Java Unit Testing - JUnit (2)Java Unit Testing - JUnit (2)
Java Unit Testing - JUnit (2)fgianneschi
 
Design pattern template method
Design pattern template methodDesign pattern template method
Design pattern template methodNelson Firmani
 
IAD18 - Testing di un microservizio CQRS con Event sourcing
IAD18 - Testing di un microservizio CQRS con Event sourcingIAD18 - Testing di un microservizio CQRS con Event sourcing
IAD18 - Testing di un microservizio CQRS con Event sourcingAlessandro Colla
 
Javaday 2006: Java 5
Javaday 2006: Java 5Javaday 2006: Java 5
Javaday 2006: Java 5Matteo Baccan
 
C# e la Framework Class Library
C# e la Framework Class LibraryC# e la Framework Class Library
C# e la Framework Class LibraryManuel Scapolan
 
Introduzione al Test Driven Development
Introduzione al Test Driven DevelopmentIntroduzione al Test Driven Development
Introduzione al Test Driven DevelopmentEnnio Masi
 
Programmazione a oggetti tramite la macchina del caffé (pt. 2)
Programmazione a oggetti tramite la macchina del caffé (pt. 2)Programmazione a oggetti tramite la macchina del caffé (pt. 2)
Programmazione a oggetti tramite la macchina del caffé (pt. 2)Marcello Missiroli
 
Programmazione a oggetti tramite la macchina del caffé (pt. 3)
Programmazione a oggetti tramite la macchina del caffé (pt. 3)Programmazione a oggetti tramite la macchina del caffé (pt. 3)
Programmazione a oggetti tramite la macchina del caffé (pt. 3)Marcello Missiroli
 
Oracle contract by desing la gestione errori
Oracle contract by desing la gestione erroriOracle contract by desing la gestione errori
Oracle contract by desing la gestione erroriCarlo Ticozzi
 

Ähnlich wie Java OCA teoria 5 (20)

Java lezione 5
Java lezione 5Java lezione 5
Java lezione 5
 
Baby Steps TripServiceKata
Baby Steps TripServiceKataBaby Steps TripServiceKata
Baby Steps TripServiceKata
 
Java codestyle & tipstricks
Java codestyle & tipstricksJava codestyle & tipstricks
Java codestyle & tipstricks
 
Eccezioni in java
Eccezioni in javaEccezioni in java
Eccezioni in java
 
Corso Java
Corso JavaCorso Java
Corso Java
 
Corso pratico di C# - 2013
Corso pratico di C# - 2013Corso pratico di C# - 2013
Corso pratico di C# - 2013
 
Corso Programmazione Java Base
Corso Programmazione Java BaseCorso Programmazione Java Base
Corso Programmazione Java Base
 
Googletest, tdd e mock
Googletest, tdd e mockGoogletest, tdd e mock
Googletest, tdd e mock
 
Guida all'utilizzo di OpenFOAM su Windows10 (con Ubuntu LTS) - Capitolo 2
Guida all'utilizzo di OpenFOAM su Windows10 (con Ubuntu LTS) - Capitolo 2Guida all'utilizzo di OpenFOAM su Windows10 (con Ubuntu LTS) - Capitolo 2
Guida all'utilizzo di OpenFOAM su Windows10 (con Ubuntu LTS) - Capitolo 2
 
Java Unit Testing - JUnit (2)
Java Unit Testing - JUnit (2)Java Unit Testing - JUnit (2)
Java Unit Testing - JUnit (2)
 
Design pattern template method
Design pattern template methodDesign pattern template method
Design pattern template method
 
IAD18 - Testing di un microservizio CQRS con Event sourcing
IAD18 - Testing di un microservizio CQRS con Event sourcingIAD18 - Testing di un microservizio CQRS con Event sourcing
IAD18 - Testing di un microservizio CQRS con Event sourcing
 
Javaday 2006: Java 5
Javaday 2006: Java 5Javaday 2006: Java 5
Javaday 2006: Java 5
 
Java5
Java5Java5
Java5
 
C# e la Framework Class Library
C# e la Framework Class LibraryC# e la Framework Class Library
C# e la Framework Class Library
 
Introduzione al Test Driven Development
Introduzione al Test Driven DevelopmentIntroduzione al Test Driven Development
Introduzione al Test Driven Development
 
Programmazione a oggetti tramite la macchina del caffé (pt. 2)
Programmazione a oggetti tramite la macchina del caffé (pt. 2)Programmazione a oggetti tramite la macchina del caffé (pt. 2)
Programmazione a oggetti tramite la macchina del caffé (pt. 2)
 
Programmazione a oggetti tramite la macchina del caffé (pt. 3)
Programmazione a oggetti tramite la macchina del caffé (pt. 3)Programmazione a oggetti tramite la macchina del caffé (pt. 3)
Programmazione a oggetti tramite la macchina del caffé (pt. 3)
 
Dal C a Java (2/3)
Dal C a Java (2/3)Dal C a Java (2/3)
Dal C a Java (2/3)
 
Oracle contract by desing la gestione errori
Oracle contract by desing la gestione erroriOracle contract by desing la gestione errori
Oracle contract by desing la gestione errori
 

Mehr von Valerio Radice

SPRING - MAVEN - REST API (ITA - Luglio 2017)
SPRING - MAVEN - REST API (ITA - Luglio 2017)SPRING - MAVEN - REST API (ITA - Luglio 2017)
SPRING - MAVEN - REST API (ITA - Luglio 2017)Valerio Radice
 
Introduzione a Sass e Less (ITA)
Introduzione a Sass e Less (ITA)Introduzione a Sass e Less (ITA)
Introduzione a Sass e Less (ITA)Valerio Radice
 
Introduzione a Docker (Maggio 2017) [ITA]
Introduzione a Docker (Maggio 2017) [ITA]Introduzione a Docker (Maggio 2017) [ITA]
Introduzione a Docker (Maggio 2017) [ITA]Valerio Radice
 
Introduzione a Git (ITA - 2017)
Introduzione a Git (ITA - 2017)Introduzione a Git (ITA - 2017)
Introduzione a Git (ITA - 2017)Valerio Radice
 
Analisi di tecnologie per l’interazione dei visitatori all'interno di musei
Analisi di tecnologie per l’interazione dei visitatori all'interno di museiAnalisi di tecnologie per l’interazione dei visitatori all'interno di musei
Analisi di tecnologie per l’interazione dei visitatori all'interno di museiValerio Radice
 
Interaction design ciccarelli_nota_radice_explor_amobile by lara
Interaction design ciccarelli_nota_radice_explor_amobile by laraInteraction design ciccarelli_nota_radice_explor_amobile by lara
Interaction design ciccarelli_nota_radice_explor_amobile by laraValerio Radice
 
Slide Tesi Valerio Radice - Portale Ricambi
Slide Tesi Valerio Radice - Portale RicambiSlide Tesi Valerio Radice - Portale Ricambi
Slide Tesi Valerio Radice - Portale RicambiValerio Radice
 

Mehr von Valerio Radice (10)

Java OCA teoria 6
Java OCA teoria 6Java OCA teoria 6
Java OCA teoria 6
 
Java OCA teoria 4
Java OCA teoria 4Java OCA teoria 4
Java OCA teoria 4
 
SPRING - MAVEN - REST API (ITA - Luglio 2017)
SPRING - MAVEN - REST API (ITA - Luglio 2017)SPRING - MAVEN - REST API (ITA - Luglio 2017)
SPRING - MAVEN - REST API (ITA - Luglio 2017)
 
Introduzione a Sass e Less (ITA)
Introduzione a Sass e Less (ITA)Introduzione a Sass e Less (ITA)
Introduzione a Sass e Less (ITA)
 
Introduzione a Docker (Maggio 2017) [ITA]
Introduzione a Docker (Maggio 2017) [ITA]Introduzione a Docker (Maggio 2017) [ITA]
Introduzione a Docker (Maggio 2017) [ITA]
 
Introduzione a Git (ITA - 2017)
Introduzione a Git (ITA - 2017)Introduzione a Git (ITA - 2017)
Introduzione a Git (ITA - 2017)
 
Analisi di tecnologie per l’interazione dei visitatori all'interno di musei
Analisi di tecnologie per l’interazione dei visitatori all'interno di museiAnalisi di tecnologie per l’interazione dei visitatori all'interno di musei
Analisi di tecnologie per l’interazione dei visitatori all'interno di musei
 
Interaction design ciccarelli_nota_radice_explor_amobile by lara
Interaction design ciccarelli_nota_radice_explor_amobile by laraInteraction design ciccarelli_nota_radice_explor_amobile by lara
Interaction design ciccarelli_nota_radice_explor_amobile by lara
 
Slide Tesi Valerio Radice - Portale Ricambi
Slide Tesi Valerio Radice - Portale RicambiSlide Tesi Valerio Radice - Portale Ricambi
Slide Tesi Valerio Radice - Portale Ricambi
 
VLR2009 - Web Office
VLR2009 - Web OfficeVLR2009 - Web Office
VLR2009 - Web Office
 

Java OCA teoria 5

  • 2. Valerio Radice valerio.radice@nextre.it WEB DEVELOPER & TEACHER https://github.com/valix85 https://plus.google.com/+ValerioRadice85 https://it.linkedin.com/in/valix85/it
  • 3. Di cosa si parlerà ?  Invocazione virtuale dei metodi  Eccezioni, gestione e creazione  Catturare e rilanciare eccezioni  NullPointer  Operazioni lambda, Predicate e principali operazioni  Stream
  • 4. Invocazione virtuale dei metodi Un'invocazione a un metodo m può definirsi virtuale quando m è definito in una classe A, ridefinito nella sottoclasse B(override) e invocato su un'instanza di B tramite una reference di A(polimorfismo per dati). Il compilatore pensa di avviare il metodo m di A(virtualmente) ma in realtà viene invocato il metodo m della classe B! Quello che avviene è che il metodo m di B ha sovrascritto lo stesso intervallo di puntamento che usa A Giocatore g4 = new GiocatoreArcade("Pong"); System.out.println(g4.toString()); Giocatore Creato GiocatoreArcade{punteggio=0, nominativo='Bipede da sala giochi', id=12012, gioco='Pong'}
  • 5. Eccezione Situazione imprevista che può presentarsi durante il flusso di un'applicazione. Alcune eccezioni possono essere catturate per gestire una risposta del sistema evitando un errore fatale che ne comprometta l'esecuzione. Vengono implementate dalla sottoclasse Exception di Throwable. public static void main(String[] args) { int x = 3; int y = 0; int ris = x/y; }
  • 7. Eccezioni public static void main(String[] args) { int x = 3; int y = 0; try{ int ris = x/y; }catch(ArithmeticException e){ System.out.println("DivBy 0! exception"); } }
  • 8. try - catch Le eccezioni oltre che ad essere generate possono essere lanciate in situazioni previste per poter reagire di conseguenza, possono essere create e manipolate. I casi di eccezione possono essere gestiti in blocchi di codice di tipo try – catch. All'interno del blocco try si inserisce il blocco di codice che potrebbe sollevare un'eccezione, mentre i blocchi catch catturano una o più eccezioni, dalla meno generica alla più generica (Exception). I comandi per gestire le eccezioni sono: try , catch , finally , throw e throws
  • 9. try Nel blocco try si inserisce del codice che potrebbe sollevare eccezioni, solitamente al fine di una gestione più lineare si consiglia di effettuare la dichiarazione al di fuori e l'assegnamento al suo interno. Qualsiasi istruzione, all'interno del blocco try, eseguita dopo quella che solleva l'eccezione NON sarà raggiunta se l'eccezione sarà sollevata. try{ int ris = x/y; System.out.println("Non stampo in caso di DivBy 0"); }
  • 10. catch I blocchi di catch servono per catturare una o più eccezioni, anche qui vale l'ereditarietà, se catturo prima un'eccezione più generica non potrò catturare dopo quella più specifica, il compilatore darà errore! Si può eseguire un solo blocco di catch alla volta! Dopo un blocco di catch il programma riprenderà da dopo il blocco try e non da dopo l'istruzione che ha generato l'errore! ... }catch(ArithmeticException e){ System.out.println("DivBy 0! exception"); }catch(Exception e){ //TODO... }
  • 11. e.printStackTrace() Lo stack è la sequenza di metodi richiamati per eseguire un'operazione. Il metodo e.printStackTrace() serve a stampare l'ordine delle chiamate (con informazioni aggiuntive) richiamate a partire dalla riga che ha generato l'errore. Sono presenti il nome del metodo, il nome del file e la riga in cui è avvenuta l'eccezione, l'insieme dei metodi che hanno portato all'esecuzione di quest'ultimo, e il tipo di di eccezione con il relativo message.
  • 12. finally Un blocco di codice finally è definito sempre dopo l'ultimo blocco di catch dichiarato. Non può esistere un try senza catch o senza un finally, posso avere un blocco try/catch oppure un blocco try/finally oppure un blocco try/catch/finally. }catch(Exception e){ //TODO... }finally{ System.out.println("istruzioni sempre eseguite"); }
  • 13. throw Le eccezioni possono essere comandate, in casi particolari potrebbe essere necessario lanciare delle eccezioni e lo si può fare all'interno di un blocco try creando una nuova eccezione e lanciarla con la keyword throw. Attenzione tutto il blocco di codice interessato dopo la dichiarazione del lancio di una nuova eccezione sarà codice irraggiungibile e pertanto il compilatore darà errore. try{ throw new NullPointerException("Messaggio opzionale"); //int ris = x/y; //System.out.println("Non stampo in caso di DivBy 0"); }catch(NullPointerException ex) { System.out.println(ex.getMessage()); }finally { System.out.println("Messaggio sempre stampato"); }
  • 14. throws Gli errori che vengono sollevati volontariamente possono essere catturati e gestiti subito, grazie a un blocco di catch, oppure possono essere rimandati al metodo chiamante, delegando al chiamante come comportarsi in caso di errore. Il chiamante dovrà quindi o inserire il metodo che potrebbe generare l'errore in un blocco try/catch e quindi potrà scegliere come gestire l'eccezione oppure potrà a sua volta rilanciarla a chi lo ha chiamato, così via fino al sistema operativo della JVM che bloccherà il processo che causa l'eccezione interrompendo l'esecuzione del programma. public static void main(String[] args) throws NullPointerException {
  • 15.
  • 16.
  • 17. Errore L'errore è una situazione imprevista non dipendente da un errore commesso dallo sviluppatore. Gli errori non sono gestibili! Vengono implementati dalla sottoclasse Error di Throwable.
  • 18. Gerarchia Errori ed eccezioni possono essere categorizzate in checked e unchecked exception.  Quelle in rosso (RuntimeException e derivate) sono situazioni non prevedibili a priori, dipendono da eventi esterni (input di utenti ecc..) e sono dette UNCHECKED.  Tutte le altre son prevedili e controllabili, vengono chiamate CHECKED.
  • 19. Errore ed Eccezione Non bisogna confondere errori ed eccezioni: Errore = situazione / problema che un programma non può risolvere Eccezione = problema non critico, gestibile e prevedibile. Sia errore che eccezione vengono "lanciati" e sono entrambi figli della classe Throwable. In caso di lancio di un'eccezione la JVM crea un'oggetto della classe Throwable (o derivata) e crea un rapporto dettagliato (stacktrace) sull'accaduto, interrompe il flusso per poi riprenderlo dopo il catch. Posso catturare più eccezioni in un blocco catch dividendole con " | " (>=java7). Un blocco finally verrà sempre eseguito per ultimo, anche dopo il catch, anche in caso non ci siano catch (try finally) in caso di eccezione il finally viene eseguito e dopo il programma terminerà in modo anomalo. catch(ArithmeticException | EmptyStackException ex) {
  • 20. try with resources (>=Java7)  Meccanismo che permette la chiusura automatica degli oggetti che per essere usati devono essere aperti (es: stream).  Gli oggetti che devono essere istanziati e aperti sono tutti dichiarati nel blocco di parentesi tonde tra il try e il suo statement.  Tali oggetti non dovranno essere chiusi prima della fine del blocco try, ma è come se i comandi di chiusura si trovassero automaticamente all'interno di un blocco finally.
  • 21. try with resources (>=Java7) Se durante il try venisse sollevata un'eccezione essa verrebbe considerata come prioritaria rispetto ad altre che potrebbero generarsi dalla chiusura degli oggetti dichiarati dal blocco di reources. Queste altre eccezioni verranno marcate come suppressed ma non verranno perse, ma saranno accessibili come attributo dell'eccezione catturata col metodo getSuppressed(). Gli oggetti utilizzabili dentro a un blocco resources devono obbligatoriamente implementare l'interfaccia AutoCloseable o Closeable.
  • 22. warnings Non si tratta di veri e propri errori ma piuttosto di segnalazioni che alcuni statement potrebbero portare, in altri contesti, a generare delle eccezioni che non gestisco. È possibile informare il compilatore per dirgli di ignorare uno o più warnings con l'annotazione @SuppressWarning("nomeDelWarning") sulla classe che lo solleva. @SuppressWarnings("serial")
  • 23. throws e override Quando si fa un override non è possibile specificare clausole di throws che non siano già presenti in quello originale o che non siano figlie della stessa classe. Devo sempre avere un sottoinsieme delle eccezioni (o al massimo uguali) a quelle del padre. Il non dichiararla è un sottoinsieme vuoto di quelle del padre e quindi sempre valido (ecco perché la SottoClasseCorretta3 è corretta!)
  • 24. Eccezioni personalizzate  Per generare una class Exception personalizzata è sufficiente estendere la classe Exception (o una sua eccezione).  È possibile, proprio come nelle classi, definire attributi e metodi personalizzati.  In particolare si può ridefinire il metodo getMessage() o altri metodi comuni, istanziare un logger per loggare in automatico le eccezioni. public class RandomException extends Exception { RandomException(){ super("Random Exception generated"); } @Override public String toString() { return getMessage() + " : numero sfortunato"; } }
  • 25. Assertion Le asserzioni devono il loro successo alla progettazione per contratto, ovvero una tecnica di programmazione per la quale si testa l'applicazione in tre stati(asserzioni): precondizione, postcondizione e invarianti. Molto usata per scrivere test. Precondizione = sviluppatore asserisce a come deve trovarsi l'applicazione prima di invocare un'operazione (non confondere con eccezione!) Postcondizione = sviluppatore asserisce a come dovrà essere lo stato di un'applicazione al termine dell'esecuzione di un'operazione. È un modo utile per asserire a cosa fare ma non dice il come. Invariante = serve a specificare vincoli su oggetti istanziati (consente stati di inconsistenza temporanei, ma poi deve tornare consistente)
  • 26. Asserzione L'asserzione è invece una condizione di verità che deve sempre essere verificata. Essa rappresenta uno strumento per testare la robustezza del software. Le asserzioni possono essere abilitate in fase di sviluppo o test e disabilitate in fase di produzione affinché il programma non subisca rallentamenti. In caso di asserzione non verificata l'esecuzione verrà interrotta. Per generare un'asserzione la si dichiara con la keyword assert. (lanciare la VM col parametro –ea ) (-ea è enableassertion) int y = 0; assert y!=0;
  • 27. assert  La parola chiave assert serve per asserire un valore di verità. Per poter funzionare si deve avviare la JVM con il parametro –ea. Con -da si disabilitano, ma basta avviarla senza parametri dato che di default sono disabilitate.  Con il comando -esa si abilitano le asserzioni anche nelle librerie di sistema.  È possibile abilitare e disabilitare le asserzioni anche a livello di package  Permette di definire un vincolo di verità che se non verificato genera un errore
  • 28. Interfaccia funzionale Interfaccia che contiene un solo metodo ASTRATTO (detto anche SAM acronimo di Simple Abstract Method). Un'interfaccia è funzionale anche se ha altri metodi ma marcati come default con un corpo proprio, l'importante è che sia UNO solo quello astratto. Java8 ha un package con sole interfacce funzionali: java.lang.function Un'interfaccia funzionale viene spesso implementata da una funzione lambda
  • 29. Lambda Un espressione lambda è detta anche funzione anonima (anonymous function), non è un metodo appartenente ad una classe e chiamato tramite un oggetto, ma una funzione senza nome definita al volo in maniera simile come le classi anonime. Solitamente si usa per implementare un'interfaccia funzionale al volo.
  • 30. Classe anonima Prima quando dovevamo implementare una classe anonima scrivevamo: new Thread(new Runnable){ @Override public void run(){ System.out.println("di Java 8: Classe anonima "); } }).start();
  • 31. Lambda Grazie alle lambda possiamo dimezzare il codice rimuovendo la parte che può dedurre tranquillamente il compilatore, possiamo avere una sintassi di questo tipo: ha la stessa valenza della classe anonima scritta precedentemente riducendo il nostro codice da 5 linee a un'unica linea di codice. new Thread(() -> System.out.println("Java 8: Funzione anonima")).start();
  • 32. Espressione Lambda L'espressione lambda può essere referenziata con una reference di un interfaccia funzionale, e la sua definizione non è altro che l'implementazione dell'unico metodo astratto dell'interfaccia funzionale, la nostra espressione lambda in sostanza può sostituire un'interfaccia funzionale.  Si concentra su cosa fare e non sul come farlo.  Riduzione del codice
  • 33. Espressione Lambda Riduzione del codice È possibile omettere parentesi tonde o graffe ove fossero necessarie per riuscire a ridurre il tutto a una sola linea di codice, questo solo se la riga di codice prevede una sola e unica istruzione, altrimenti bisognerà utilizzare le parentesi dove ne necessitiamo.
  • 34. Espressione Lambda: sintassi parametro1 -> comando(parametro1) (Tipo parametro1) -> comando(parametro1) (parametro1,parametro2) -> {implementazione con return} Il simbolo "->" serve a dividere i parametri (numero e tipo automaticamente dedotti) dall'implementazione, che se monofunzione non richiede parentesi graffe e NON vuole il return (errore di compilazione), in caso di più funzioni/operazioni le graffe e il return diventano obbligatorie; anche return; senza nulla è valido in caso di void.
  • 35. Espressione Lambda: visibilità All'interno di una classe anonima, il reference this si riferisce all'oggetto corrente istanziato dalla classe anonima, e per riferirsi ai membri della classe che include la classe anonima dobbiamo utilizzare una sintassi di questo genere: NomeCasseEsterna.this.nomeMembro con l'espressione lambda invece, il reference this si riferisce alla classe in cui è inclusa l'espressione. Vedi esempio seguente
  • 36. Espressione Lambda: visibilità public class LambdaThis{ private String stringa = "Variabile d'istanza di classe"; public void metodoContenenteLambda(){ String stringa = "variabile locale del metodo contenente"; new Thread(()-> System.out.println(this.stringa).start()); new Thread(()-> System.out.println(stringa).start()); } public static void main(String[] args) { LambdaThis lambdaThis = new LambdaThis(); lambdaThis.metodoContenenteLambda(); } }
  • 37. Espressione Lambda: visibilità Per quanto riguarda le variabili locali dichiarati all'interno di un espressione lambda, esse condivido lo stesso scope (visibilità) con il blocco di codice dove sono definite. Come le classi anonime anche le espressioni lambda possono utilizzare le variabili esterne solo se sono state dichiarate final o sono effettivamente non modificabili. In molti casi il compilatore si accorge se tentiamo di modificare una variabile dichiarata esternamente. Un trucco per “ingannare” il compilatore c'è, infatti benché una variabile dichiarata final, e quindi non modificabile, possiamo “wrappare” il valore della nostra variabile, modificando la struttura interna, senza che crei problemi al compilatore.
  • 38. Espressione Lambda: eccezioni Quando utilizziamo le espressioni lambda bisogna fare attenzione alle eccezioni cheked exception, ovvero eccezioni che NON sono sottoclassi di RuntimeException. Per sviare questo problema bisognerebbe usare il throws della dichiarazione del metodo che potrebbe lanciare l'eccezione nel caso non siano gestite. Purtroppo le lambda non dichiarano metodi, e non sarebbe possibile utilizzare la clausola throws se non nel metodo dell'interfaccia funzionale che rappresentano.
  • 39. Espressione Lambda: eccezioni new Thread(() -> { Thread.sleep(1000); System.out.println("Hello World"); }).start(); questo tipo di codice darà luogo ad un errore di compilazione, e per risolverlo abbiamo due possibilità:  gestire tutto con il try –catch  utilizzare un'interfaccia funzionale che definisca il metodo astratto con la clausola throws richiesta
  • 40. Espressione Lambda L'obbiettivo delle espressioni lambda è il passaggio dinamico di algoritmi implementati "al volo" come parametri di metodi. Di fatto una lambda è la sola implementazione di un'interfaccia funzionale quando necessario.
  • 41. Espressione Lambda: referenza a metodo statico Un modo per implementare una lambda è l'utilizzo della chiamata ai metodi statici (referenza a metodo).  NomeClasse : : nomeDelMetodoStatico Quando si ha un metodo statico che accetta un solo parametro il compilatore è in grado di autodedurre tutte le informazioni necessarie (tipo e ordine). public class Filtri{ public static boolean isFilmDiFantascienza(Film film){ return "Fantascienza".equals(film.getGenere()); } } ... Film[] filmDiFantascienza = videoteca.getFilmFiltrati(Filtri::isFilmDiFantascienza);
  • 42. Espressione Lambda: referenza a metodo d'istanza Stesso principio precedente applicato però non più su una classe ma su un'istanza (oggetto) di essa.  NomeOggetto : : nomeDelMetodoDIstanza public class OridnamentoFilm { public int ordinamentoPerNome(Film film, Film film1){ return film.getNome().compareTo(film1.getNome()); } } ... Film[] catalogo = videoteca.getFilm(); OrdinamentoFilm of1 = new OrdinamentoFilm(); ... Arrays.sort(catalogo, of1::ordinamentoPerNome);
  • 43. Espressione Lambda: referenza a metodo d'istanza di un certo tipo Stesso principio dei precedente applicato però a un metodo non statico di una classe senza però averne un'istanza.  NomeClasse : : nomeDelMetodoDIstanza Il metodo di istanza è un metodo non statico, ma richiamato attraverso la classe. Collections.sort(myCollection, String::compareToIgnoreCase());
  • 44. Espressione Lambda: referenza a costruttore In questo caso non ci si riferisce a un metodo statico in quanto il costruttore rappresenta un'oggetto. Si otterrà un'istanza di quella classe. Mi permette di evitare classe Factory.  NomeClasse : : new
  • 45. Package java.lang.function "Functional interfaces provide target types for lambda expressions and method references."
  • 46. Interfaccia Predicate  Un metodo astratto (è funzionale!) test()  Accetta un predicato (confronto)  Ritorna un booleano (Ottima per i test)  Ideale per filtrare gli oggetti  Possibilità di concatenare metodi: or(), xor(), e and()
  • 47. Interfaccia Consumer  Un metodo astratto (è funzionale!) accept()  Accetta un predicato (confronto)  Ritorna un void  Utile a cambiare lo stato interno dell'oggetto passato / consumarlo  Possibilità di concatenare metodi: andThen()
  • 48. Interfaccia Supplier  Un metodo astratto (è funzionale!) get()  Ritorna un'istanza del tipo generico con la quale è dichiarata  Utile a creare istanze / factory methods
  • 49. Interfaccia Function  Un metodo astratto (è funzionale!) apply()  Permette di astrarre il concetto di funzione  Utile a modificare il dato
  • 50. Interfaccia Bi-Function  Un metodo astratto (è funzionale!) apply()  Permette di astrarre il concetto di funzione a due parametri  Utile a modificare i dati, ritornando un solo dato  Esistono anche Bi-Supplier e Bi-Predicate
  • 51. Interfaccia Unary Operator  Un metodo astratto (è funzionale!) apply(), ereditato da Function  Permette di astrarre il concetto di trasformazione sul parametro  Utile a trasformare un dato in ingresso  Ritorna lo stesso tipo in ingresso  Utile per combinare più espressioni lambda dello stesso tipo
  • 52. Stream  Lo Stream è una nuova interfaccia definita all'interno del package java.util.stream  rappresenta un flusso che ha come sorgente una collezione di dati, e sul quale si possono eseguire operazioni, facendo utilizzo delle lambda e reference a metodi  Lo stream solitamente viene creato a partire da una determinata collezione, tramite la chiamata del metodo stream().
  • 53. Stream È possibile istanziare uno stream passando un array al metodo statico of(): Stream <String> stringStream=Stream.of(arrayDiStringhe); Passando all'altra versione del metodo of() direttamente dei valori: Stream<String> stringStream=Stream.of(“Take”,“The”,“Time”); Tramite il metodo statico generate() delle stessa classe Stream, ci fornisce uno stream infinito perché ogni volta che vogliamo un valore dallo stream ne verrà creato uno: Stream<Double> randomDouble=Stream.generate(Math.random); Questo esempio di codice usando una reference al metodo random() della classe Math restituisce un numero casuale di tipo double maggio o uguale di 0.0 e minore di 1.
  • 54. Stream È possibile iterare sulle collezioni utilizzando un' oggetto Stream, che definisce anche un metodo forEach(), e da esso possiamo usufruire delle cosiddette “operazioni di aggregazione” utilizzate in combinazione alle espressioni Lambda. È anche possibile concatenare le operazioni per creare delle pipeline. Lo stream non immagazzina elementi, ma permette di operare su di essi attraverso una serie di operazioni: le pipeline Smartphones .stream() .filters(s ->”Sasmsung”.equals(s.getMarca()) .forEach(s → Sout(s));
  • 55. Pipeline  Rappresenta un insieme di operazioni da eseguirsi su un flusso dati ( stream ).  Le operazioni per creare ed usare una pipeline sono;  Aprire una sorgete (ottenere uno stream)  Eseguire zero o più operazioni di aggregazione / riduzione / intermedie  Eseguire un metodo / operazione terminale per usare/raccogliere i dati modificati.
  • 57. Pipeline: 3 componenti fondamentali  Una sorgente: potrebbe essere una collezione o un array, o altri canali di input/output, oppure il metodo generate() della classe Stream stessa, quindi per ottenere un oggetto Stream la sorgente deve mettere a disposizione un metodo.  Zero o più operazioni di aggregazione (o intermedie): queste tipi di operazione hanno la caratteristica di ritornare un nuovo oggetto Stream, esempio il metodo filter(). Altri tipi di metodi che abbiamo a disposizione sono map(), mapToDouble(). Questi e tanti altri metodi intermedi sono chiamati “metodi lazy(pigri)”, perché vengo chiamati all'ultimo momento, ovvero saranno invocati solo quando sarà invocato il metodo terminale, che ovviamente ha bisogno di metodi intermedi per essere eseguito.  Un' operazione terminale: metodo che restituisce un risultato che non è oggetto Stream, ad es: Collect.
  • 58. Optional  Consente di evitare i NullPointerException nel caso in cui una pipeline non ritorni nulla.  Esistono OptionalDouble, OptionalLong, OptionalInt e Optional<T>  Potrebbero sollevare NoSuchElementException  Facilmente evitabile usando il metodo .orElse() che specifica cosa fare in caso in cui l'optional sia vuoto
  • 59. Optional: esempio //double prezzoMedio = negozio OptionalDouble prezzoMedio = negozio .stream() .filter(s->s.getMarca().equalsIgnoreCase("nokia")) .mapToDouble(s->s.getPrezzo()) .average(); //.getAsDouble(); //System.out.println(prezzoMedio); System.out.println(String.format("%.2f",prezzoMedio.orElse(0)));
  • 60. Reduction Operation  metodo che a partire dagli elementi di uno stream, ritorna un solo valore.  Le tipiche implementazioni di operazione di riduzione sono min(), max(), sum(), average(), count() ...  Altre operazioni di riduzioni possono tornare delle collezioni, es reduce() e collect()
  • 61. Metodo Reduce Esiste in più versioni (overload), la più famosa ha: - Un oggetto detto identity che rappresenta il valore iniziale - Un oggetto BinaryOperator (accumulator) che rappresenta un'espressione lambda a due parametri Il valore di reduce ritorna ad essere come il primo argomento della BiFunction.
  • 62. Metodo Collect Usato con i metodi statici della classe Collectors, anch'esso esiste in più versioni (overload): - Possiamo ottenere liste con Collectors.toList() (si duplicati) - Possiamo ottenere dei Set (no duplicati) - Consente operazioni di reducing(), groupingBy(), toList(), toCollection()