Esercizi
- Home
- Esercizi del capitolo 14 e dell'appendice H
Esercizi del capitolo 14 e dell'appendice H
Stream API e Framework
Collections
I prossimi esercizi riguardano sia i capitolo 14 che l'appendice H. Infatti, gli argomenti
riguardanti la Stream API, sono spesso collegati con le collection, e quindi non distingueremo i due
argomenti con la numerazione degli esercizi. Queste ultime, sono tra le implementazioni più
utilizzate in assoluto in Java. La documentazione è fondamentale, per essere programmatori migliori
bisognerebbe consultarla assiduamente. Essendo una libreria molto estesa, ci sarà sempre un metodo o
un'implementazione che fa al caso nostro, che non abbiamo mai utilizzato. La Stream API ora ha
ulteriormente ampliato gli orizzonti d'applicazione delle collection.
Di seguito trovate gli esercizi del capitolo.
Per ogni esercizio, cliccando sulla traccia potete vedere la relativa soluzione.
Gli esercizi caratterizzati dall'icona sono
considerati i più complessi relativamente agli argomenti trattati.
Se preferite lavorare offline, è possibile scaricare tutti gli esercizi e le relative
soluzioni in formato PDF nella sezione download.
-
Esercizio 14.a) Framework Collections, Vero o Falso:
1.
Collection
,Map
,SortedMap
,Set
,List
eSortedSet
sono interfacce e non possono essere istanziate.
2. UnSet
è una collezione ordinata di oggetti; unaList
non ammette elementi duplicati ed è ordinata.
3. Le mappe non possono contenere chiavi duplicate ed ogni chiave può essere associata ad un solo valore.
4. Esistono diverse implementazioni astratte da personalizzare nel framework comeAbstractMap
.
5. UnaHashMap
è più performante rispetto ad unaHashtable
perché non è sincronizzata.
6. UnaHashMap
è più performante rispetto ad unTreeMap
ma quest'ultima, essendo un'implementazione diSortedMap
, gestisce l'ordinamento.
7.HashSet
è più performante rispetto aTreeSet
ma non gestisce l'ordinamento.
8.Iterator
edEnumeration
hanno lo stesso ruolo ma quest'ultima permette durante le iterazioni di rimuovere anche elementi.
9.ArrayList
ha prestazioni migliori rispetto aVector
perché non è sincronizzato, ma entrambi hanno meccanismi per ottimizzare le prestazioni.
10. La classeCollections
è una lista diCollection
.
Soluzione
1. Vero.
2. Falso.
3. Vero.
4. Vero.
5. Vero.
6. Vero.
7. Vero.
8. Falso.
9. Vero.
10. Falso. -
Esercizio 14.b) Stream API, Vero o Falso:
1.
Stream
è una classe che implementaCollection
.
2. È possibile iterare su uno stream in entrambe le direzioni.
3. Una pipeline è costituita da una sorgente, metodi di aggregazione opzionali e un metodo terminale.
4. Il metodomap
è da considerarsi un metodo di aggregazione.
5.Optional
è un'interfaccia che permette di evitare di avere a che fare con leNullPointerException
.
6. I metodi di riduzione sono operazioni di aggregazione.
7. Il metodojoining
diStream
permette di concatenare stringhe con dei separatori di tipo stringa.
8. La classeDoubleSummaryStatistics
è un particolare stream.
9. Il metodoparallelStream
ritorna uno stream capace di usare l'algoritmo Fork/Join per eseguire operazioni sugli elementi di una collection.
10. Uno stream è istanziabile solo a partire da una collezione.
Soluzione
1. Falso,
Stream
è un'interfaccia.
2. Falso.
3. Vero.
4. Vero.
5. Falso,Optional
è una classe (peraltro dichiaratafinal
e quindi non estendibile).
6. Falso, sono operazioni terminali.
7. Falso, il metodojoining
appartiene alla classeCollectors
.
8. Falso.
9. Vero.
10. Falso. -
Esercizio 14.c)
Creare una collection che, nel caso si aggiungano due elementi uguali, lanci un'eccezione personalizzata (da creare anch'essa). Creare infine anche una classe di test.
Soluzione
L'eccezione personalizzata potrebbe essere la seguente:
package com.claudiodesio.eccezioni; public class DuplicatoException extends RuntimeException { public DuplicatoException(Object elementoDuplicato) { super("Impossibile aggiungere l'elemento \"" + elementoDuplicato + "\" perché già presente"); } }
Mentre potremmo codificare la collection richiesta in questo modo:
package com.claudiodesio.collections; import com.claudiodesio.eccezioni.DuplicatoException; import java.util.HashSet; public class SetRobusto<E> extends HashSet<E> { @Override public boolean add(E e) { boolean result = super.add(e); if (!result) { throw new DuplicatoException(e); } return result; } }
Ed ecco una classe di test:
package com.claudiodesio; import com.claudiodesio.collections.SetRobusto; import com.claudiodesio.eccezioni.DuplicatoException; public class TestSetRobusto { public static void main(String args[]) { SetRobusto<String> set = getSetRobusto(); try { set.add("Italia"); } catch (DuplicatoException duplicatoException) { System.out.println(duplicatoException.getMessage()); } System.out.println(set); } public static SetRobusto<String> getSetRobusto() { SetRobusto<String> set = new SetRobusto<>(); set.add("Italia"); set.add("Francia"); set.add("Polonia"); set.add("Germania"); set.add("Inghilterra"); set.add("Spagna"); set.add("Grecia"); set.add("Olanda"); set.add("Portogallo"); set.add("Belgio"); return set; } }
L'output sarà:
Impossibile aggiungere l'elemento "Italia" perché già presente [Germania, Inghilterra, Francia, Belgio, Polonia, Olanda, Italia, Spagna, Grecia, Portogallo]
-
Esercizio 14.d)
Creare una mappa chiamata
MappaIncrementale
, che permette di aggiungere più valori (ordinati in ordine di aggiunta) alla stessa chiave. Creare anche una classe di test.
Soluzione
Il listato della mappa richiesta potrebbe essere il seguente:
package com.claudiodesio.collections; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; public class MappaIncrementale<K, V> extends HashMap<K, Collection<V>> { public void add(K key, V value) { if (this.get(key) == null) { Collection<V> collection = new ArrayList<>(); collection.add(value); this.put(key, collection); } else { Collection<V> collection = this.get(key); collection.add(value); } } }
Si noti che il metodoadd
non è un override (il metodo per aggiungere coppie chiave-valore è il metodoput
) bensì un metodo ad hoc.
Segue una classe di test:
package com.claudiodesio.test; import com.claudiodesio.collections.MappaIncrementale; import com.claudiodesio.collections.SetRobusto; import java.util.Iterator; public class TestMappaIncrementale { public static void main(String args[]) { MappaIncrementale<Integer, String> mappa = new MappaIncrementale<>(); riempiMappaIncrementale( mappa); System.out.println(mappa); } public static void riempiMappaIncrementale( MappaIncrementale<Integer, String> mappa) { SetRobusto<String> set = TestSetRobusto.getSetRobusto(); int i = 1; int j = 1; Iterator<String> iterator = set.iterator(); while (iterator.hasNext()) { if (i % 3 == 0) { j++; } String string = iterator.next(); mappa.add(j, string); i++; } } }
che genera il seguente output:
{1=[Germania, Inghilterra], 2=[Francia, Belgio, Polonia], 3=[Olanda, Italia, Spagna], 4=[Grecia, Portogallo]}
-
Esercizio 14.e)
Sfruttando le classi create negli esercizi precedenti creare un'estensione di
MappaIncrementale
(chiamiamolaMappaIncrementaleRobusta
) che, quando si aggiunge un elemento la cui chiave esiste già, lancia un'eccezione come descritto nell'esercizio 14.c. Creare anche una classe di test.
Soluzione
Il listato della mappa richiesta potrebbe essere il seguente:
package com.claudiodesio.collections; import java.util.Collection; public class MappaIncrementaleRobusta<K, V> extends MappaIncrementale<K, V> { @Override public void add(K key, V value) { if (this.get(key) == null) { Collection<V> setRobusto = new SetRobusto<>(); setRobusto.add(value); this.put(key, setRobusto); } else { Collection<V> setRobusto = this.get(key); setRobusto.add(value); } } }
Si noti che questa volta il metodoadd
è un override, e semplicemente cambiando l'ArrayList
definito nella classeMappaIncrementale
con unSetRobusto
abbiamo risolto la situazione. Volendo potremmo fare un po' di refactoring su queste due classi in modo tale da migliorare il nostro codice. Per prima cosa ritorniamo alla classeMappaIncrementale
e riscriviamo il metodoadd
con dei piccoli accorgimenti:
package com.claudiodesio.collections; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; public class MappaIncrementale<K, V> extends HashMap<K, Collection<V>> { public void add(K key, V value) { if (this.get(key) == null) { Collection<V> collection = getCollection(); collection.add(value); this.put(key, collection); } else { Collection<V> arrayList = this.get(key); arrayList.add(value); } } protected Collection <V> getCollection() { return new ArrayList<>(); } }
In questo modo possiamo semplificare la sottoclasse:
package com.claudiodesio.collections; import java.util.Collection; public class MappaIncrementaleRobusta<K, V> extends MappaIncrementale<K, V> { @Override protected Collection<V> getCollection() { return new SetRobusto<>(); } }
Ed ottenere lo stesso risultato, senza duplicazioni di codice.
Segue la classe di test:
package com.claudiodesio.test; import com.claudiodesio.collections.MappaIncrementale; import com.claudiodesio.collections.MappaIncrementaleRobusta; import com.claudiodesio.eccezioni.DuplicatoException; public class TestMappaIncrementaleRobusta { public static void main(String args[]) { MappaIncrementale<Integer, String> mappa = new MappaIncrementaleRobusta<>(); TestMappaIncrementale.riempiMappaIncrementale(mappa); try { mappa.add(4, "Grecia"); } catch (DuplicatoException duplicatoException) { System.out.println(duplicatoException.getMessage()); } System.out.println(mappa); } }
che genera il seguente output:
Impossibile aggiungere l'elemento "Grecia" perché già presente {1=[Germania, Inghilterra], 2=[Francia, Belgio, Polonia], 3=[Olanda, Italia, Spagna], 4=[Grecia, Portogallo]}
-
Esercizio 14.f)
Dopo aver svolto l'esercizio precedente, si riempia la classe di test di oggetti
Citta
, la cui classe è stata creata nell'esercizio 13.c e che riportiamo di seguito per comodità:
package com.claudiodesio.dati; public class Citta { private String nome; private boolean capoluogo; private boolean diMare; public Citta(String nome, boolean capoluogo, boolean diMare) { this.nome = nome; this.capoluogo = capoluogo; this.diMare = diMare; } public boolean isDiMare() { return diMare; } public void setDiMare(boolean diMare) { this.diMare = diMare; } public boolean isCapoluogo() { return capoluogo; } public void setCapoluogo(boolean capoluogo) { this.capoluogo = capoluogo; } public String getNome() { return nome; } public void setNome(String nome) { this.nome = nome; } @Override public String toString() { return getNome(); } }
Aggiungere metodi
equals
ehashcode
. In una classeTestStream
, con uno stream stampare tutte le città di mare. Con un secondo stream stampare tutte le città capoluogo. Con un terzo stream stampare tutte le città che finiscono con la lettera 'a'.
Soluzione
Nella classe
Citta
aggiungiamo i metodi richiesti:
@Override public int hashCode() { int hash = 7; hash = 19 * hash + Objects.hashCode(this.nome); return hash; } @Override public boolean equals(Object obj) { if (obj == null) { return false; } if (getClass() != obj.getClass()) { return false; } final Citta other = (Citta) obj; if (!Objects.equals(this.nome, other.nome)) { return false; } return true; }
La classeTestStreams
invece potrebbe essere codificata come segue:
package com.claudiodesio.test; import com.claudiodesio.collections.SetRobusto; import com.claudiodesio.dati.Citta; public class TestStreams { public static void main(String args[]) { SetRobusto<Citta> set = getSetRobusto(); System.out.println("Città di mare:"); set.stream().filter(e->e.isDiMare()).forEach(System.out::println); System.out.println("\nCittà capoluogo:"); set.stream().filter(e->e.isCapoluogo()).forEach(System.out::println); System.out.println("\nCittà che finiscono con 'a':"); set.stream().filter(e->e.getNome().endsWith("a")). forEach(System.out::println); } public static SetRobusto<Citta> getSetRobusto() { SetRobusto<Citta> set = new SetRobusto<>(); set.add(new Citta("Milano", true, false)); set.add(new Citta("Rovigo", false, false)); set.add(new Citta("Potenza", true, false)); set.add(new Citta("Siracusa", false, true)); set.add(new Citta("Perugia", true, false)); set.add(new Citta("Napoli", true, true)); set.add(new Citta("Pescara", false, true)); set.add(new Citta("Taranto", false, true)); set.add(new Citta("Siena", false, false)); return set; } }
Segue l'output:
Città di mare: Napoli Siracusa Taranto Pescara Città capoluogo: Napoli Potenza Perugia Milano Città che finiscono con 'a': Potenza Perugia Siena Siracusa Pescara
-
Esercizio 14.g)
Riguardo il ciclo for migliorato, quali delle seguenti affermazioni sono corrette?
1. Il ciclofor
migliorato può in ogni caso sostituire un ciclofor
.
2. Il ciclofor
migliorato può essere utilizzato con gli array e con le classi che implementanoIterable
.
3. Il ciclofor
migliorato sostituisce l'utilizzo diIterator
.
4. Il ciclofor
migliorato non può sfruttare correttamente i metodi diIterator
.
5. In un ciclofor
migliorato non è possibile effettuare cicli all'indietro.
Soluzione
Le affermazioni corrette sono le numero 2, 4 e 5.
-
Esercizio 14.h)
Considerato il seguente codice:
import java.util.*; public class Esercizio14H { public static void main(String args[]) { Collection map = new HashMap(2); map.put(1,1); System.out.println(map); } }
Quali tra le seguenti affermazioni è corretta?
1. Il codice viene compilato con dei warning, ed eseguito stampa{1=1}
.
2. Il codice viene compilato con dei warning, ma lancia un'eccezione durante l'esecuzione.
3. Il codice non compila.
4. Il codice viene compilato correttamente, ed eseguito stampa{1=1}
.
5. Il codice viene compilato con dei warning, ed eseguito stampa{1=1, null=null}
.
6. Il codice viene compilato con dei warning, ed eseguito stampa{1=1, 0=0}
.
Soluzione
La risposta corretta è la numero 3 in quanto
HashMap
non estendeCollection
, e quindi non si può assegnare un reference di tipoCollection
ad unHashMap
. L'output della compilazione è infatti il seguente:
Esercizio14H.java:5: warning: [rawtypes] found raw type: Collection Collection map = new HashMap(10); ^ missing type arguments for generic class Collection<E> where E is a type-variable: E extends Object declared in interface Collection Esercizio14H.java:5: warning: [rawtypes] found raw type: HashMap Collection map = new HashMap(10); ^ missing type arguments for generic class HashMap<K,V> where K,V are type-variables: K extends Object declared in class HashMap V extends Object declared in class HashMap Esercizio14H.java:5: error: incompatible types: HashMap cannot be converted to Collection Collection map = new HashMap(10); ^ Esercizio14H.java:6: error: cannot find symbol map.put(1,1); ^ symbol: method put(int,int) location: variable map of type Collection 2 errors 2 warnings
Si noti che vengono mostrati anche due warning perché abbiamo usato raw type, e che anche gli errori sono due, perché il referencemap
, essendo di tipoCollection
, non dichiara il metodoput
(che viene dichiarato nell'interfacciaMap
). -
Esercizio 14.i)
Quali delle seguenti affermazioni sono corrette?
1. L'interfacciaIterable
dichiara il metodoforEach
.
2.Iterator
estendeIterable
.
3.Iterator
definisce il metodoforEachRemaining
.
4.Collection
implementa l'interfacciaIterable
.
Soluzione
Le risposte corrette sono le numero 1 e 3.
Iterator
non estendeIterable
, quindi l'affermazione 2 è non corretta. Nel caso dell'affermazione 4 l'affermazione sarebbe stata corretta se fosse stata:Collection
estende l'interfacciaIterable
. Infatti siaCollection
cheIterable
sono interfacce e non classi. Questo implica che una può estendere l'altra, non implementarla. -
Esercizio 14.l)
Quali delle seguenti affermazioni sono corrette?
1.Collection
è una superclasse diList
.
2. UnaCollection
può essere trasformata in un array invocando il metodotoArray
definito nella classeArrays
.
3. Un array può essere trasformato in unaCollection
mediante il metodotoCollection
della classeArrays
.
4.Collection
definisce il metodoadd
.
Soluzione
L'unica risposta corretta è la numero 4. L'affermazione numero 1 è falsa semplicemente perché
Collection
è un'interfaccia e non una classe. Per quanto riguarda l'affermazione 2, il metodotoArray
è dichiarato dall'interfacciaCollection
. Inoltre, non esiste un metodotoCollection
nella classeArrays
, quindi anche l'affermazione 3 non è corretta. -
Esercizio 14.m)
Consideriamo la seguente classe:
import java.util.*; public class Esercizio14M { public static void main(String args[]) { ArrayList<String> list = new ArrayList<>(3); list.add("*"); list.add("@"); list.set(1, "$"); ListIterator listIterator = list.listIterator(); while(listIterator.hasNext()) { System.out.println(listIterator.next()); } while(listIterator.hasPrevious()) { System.out.println(listIterator.previous()); } } }
Se eseguiamo questa classe, quale sarà l'output?
Soluzione
L'output della classe
Esercizio14M
è il seguente:
* $ $ *
Infatti vengono inseriti due elementi (le stringhe*
e@
) con il metodoadd
nella listalist
, e poi con il metodoset
viene sovrascritto la stringa@
con la stringa$
. I successivi cicli stampano gli elementi della lista ciclando con unListIterator
prima in avanti e poi all'indietro. -
Esercizio 14.n)
Si crei un semplice programma che definisca un
ArrayList
di interi, e si trovi un modo affinché venga riempito con i numeri pari che vanno da 2 a 2000000 nella maniera più efficiente.
Soluzione
La soluzione potrebbe essere la seguente classe:
import java.util.*; public class Esercizio14N { public static void main(String args[]) { ArrayList<Integer> list = new ArrayList<>(); list.ensureCapacity(1000000); long startTime = System.currentTimeMillis(); for (int i = 1; i <= 2000000; ++i) { if (i % 2 == 0) { list.add(i); } } long endTime = System.currentTimeMillis(); System.out.println("Tempo = " + (endTime - startTime)); } }
-
Esercizio 14.o)
Quali delle seguenti affermazioni sono corrette?
1. Un'implementazione diSet
non può ordinare i suoi elementi.
2. Un'implementazione diSet
non ammette più di un elementonull
.
3. L'interfacciaSet
è estesa daSortedSet
.
4. L'implementazioneHashSet
non è thread safe.
Soluzione
Tutte le affermazioni sono corrette tranne la numero 1. Infatti essendo
Set
estesa daSortedSet
(vedi affermazione numero 3), le implementazioni diSortedSet
comeTreeSet
saranno ordinate ("sorted" in inglese significa "ordinato"). La numero 2 è vera proprio in virtù del fatto che qualsiasiSet
non ammette duplicati, quindi non è possibile neanche aggiungere due volte l'elementonull
. -
Esercizio 14.p)
Quali delle seguenti affermazioni sono corrette?
1. La classeVector
è un'implementazione diList
.
2. Un'implementazione diList
non ammette elementinull
.
3. Un reference di tipoList
può diventare thread safe se gli viene assegnato
un oggetto di tipoList
che viene ritornato dal metodosynchronizedList
.
4. Per eliminare gli elementi duplicati da una lista, basta riempire unSet
con gli elementi dellaList
.
Soluzione
Le affermazioni numero 1, 3 e 4 sono corrette.
-
Esercizio 14.q)
Data la classe:
import java.util.*; public class ClaudioLinkedList extends LinkedList<String> { public ClaudioLinkedList() { add("X"); add("L"); add("W"); add("U"); add("D"); add("I"); add("Z"); } }
aggiungere nella seguente classe
Esercizio14Q
:
import java.util.*; public class Esercizio14Q { public static void main(String args[]) { ClaudioLinkedList claudioLinkedList = new ClaudioLinkedList(); /*INSERISCI CODICE QUI*/ System.out.println(claudioLinkedList); } }
il codice al posto del commento
INSERISCI CODICE QUI
, che permetterà di generare il seguente output:
[C, L, A, U, D, I, O]
Soluzione
La soluzione potrebbe essere la seguente classe:
import java.util.*; public class Esercizio14Q { public static void main(String args[]) { ClaudioLinkedList claudioLinkedList = new ClaudioLinkedList(); claudioLinkedList.removeFirst(); claudioLinkedList.addFirst("C"); claudioLinkedList.set(2, "A"); claudioLinkedList.removeLast(); claudioLinkedList.addLast("O"); System.out.println(claudioLinkedList); } }
-
Esercizio 14.r)
Se vogliamo utilizzare una mappa in maniera thread-safe, che opzioni abbiamo? Elencare almeno due opzioni.
Soluzione
Potremmo utilizzare un
Hashtable
, unaConcurrentHashMap
, oppure utilizzare un reference che punta al risultato dell'invocazione di un metodo sincronizzatoresynchronizedMap
. -
Esercizio 14.s)
Se vogliamo utilizzare una lista immutabile, che opzioni abbiamo? Elencare almeno due opzioni. E se vogliamo utilizzare un set immutabile, che opzioni abbiamo? Elencare almeno due opzioni.
Soluzione
Potremmo utilizzare un reference che punta al risultato dell'invocazione di un metodo sincronizzatore
unmodifiableList
, come riportato di seguito:
List<String> immutableList = Arrays.asList("a", "b", "c"); immutableList = Collections.unmodifiableList(immutableList);
Oppure è possibile utilizzare il metodo di convenienza staticoof
dell'interfacciaList
introdotto in Java 9:
List immutableList = List.of("a", "b", "c");
Stesso discorso per le implementazioni immutabili diSet
. Ecco i due esempi richiesti:
Set<String> immutableSet = new HashSet<>(Arrays.asList("a", "b", "c")); immutableSet = Collections.unmodifiableSet(immutableSet);
e sfruttando il metodo staticoof
dell'interfacciaSet
:
Set<String> immutableSet = Set.of("a", "b", "c");
-
Esercizio 14.t)
Considerata la lista di stringhe che ritorna il seguente metodo:
public static List<String> getStringList() { String stringa = "I ragazzi che si amano si baciano in piedi " + "Contro le porte della notte " + "E i passanti che passano li segnano a dito " + "Ma i ragazzi che si amano " + "Non ci sono per nessuno " + "Ed è la loro ombra soltanto " + "Che trema nella notte " + "Stimolando la rabbia dei passanti " + "La loro rabbia il loro disprezzo le risa la loro invidia " + "I ragazzi che si amano non ci sono per nessuno " + "Essi sono altrove molto più lontano della notte " + "Molto più in alto del giorno " + "Nell'abbagliante splendore del loro primo amore "; String[] stringhe = stringa.split(" "); return Arrays.asList(stringhe); }
scrivere una pipeline che consideri solo le parole che non iniziano con "a", e ne calcoli (e stampi) la lunghezza media.
Soluzione
Una possibile soluzione potrebbe essere la seguente:
import java.util.*; public class Esercizio14T { public static void main(String args[]) { List<String> stringList = getStringList(); Double average = stringList.stream(). filter(s -> !s.startsWith("a")).mapToInt( String::length).average().getAsDouble(); System.out.println(average); } public static List<String> getStringList() { String stringa = "I ragazzi che si amano si baciano in piedi " + "Contro le porte della notte " + "E i passanti che passano li segnano a dito " + "Ma i ragazzi che si amano " + "Non ci sono per nessuno " + "Ed è la loro ombra soltanto " + "Che trema nella notte " + "Stimolando la rabbia dei passanti " + "La loro rabbia il loro disprezzo le risa la loro invidia " + "I ragazzi che si amano non ci sono per nessuno " + "Essi sono altrove molto più lontano della notte " + "Molto più in alto del giorno " + "Nell'abbagliante splendore del loro primo amore "; String[] stringhe = stringa.split(" "); return Arrays.asList(stringhe); } }
Che produrrà il seguente output:
4.607142857142857
-
Esercizio 14.u)
Quali delle seguenti affermazioni sono corrette?
1.Optional
è un'interfaccia generica.
2. Il metodoofNullable
restituisce un oggettoOptional
che fa da wrapper all'oggetto passato in input.
3.orElseThrow
è un metodo diOptional
che restituisce un oggettoOptional
o lancia un'eccezione che può essere specificata in input, nel caso l'oggetto "wrappato" sianull
.
4.findFirst
è un metodo diOptional
che restituisce un oggettoOptional
onull
, nel caso l'oggetto "wrappato" sianull
.
Soluzione
Le affermazioni corrette sono le numero 2 e 3. L'affermazione numero 1 è scorretta perché
Optional
è una classe generica. La 4 è scorretta perchéfindFirst
è dichiarata nell'interfacciaStream
. -
Esercizio 14.v)
Considerato il seguente codice:
import java.util.*; import java.util.stream.*; public class Esercizio14V { public static void main(String args[]) { List<String> stringList = getStringList(); /*INSERISCI CODICE QUI*/ System.out.println(map); } public static List<String> getStringList() { String stringa = "I ragazzi che si amano si baciano in piedi " + "Contro le porte della notte " + "E i passanti che passano li segnano a dito " + "Ma i ragazzi che si amano " + "Non ci sono per nessuno " + "Ed è la loro ombra soltanto " + "Che trema nella notte " + "Stimolando la rabbia dei passanti " + "La loro rabbia il loro disprezzo le risa la loro invidia " + "I ragazzi che si amano non ci sono per nessuno " + "Essi sono altrove molto più lontano della notte " + "Molto più in alto del giorno " + "Nell'abbagliante splendore del loro primo amore "; String[] stringhe = stringa.split(" "); return Arrays.asList(stringhe); } }
scrivere una pipeline per creare una mappa che raggruppi le parole del testo che iniziano per la stessa iniziale, ignorando il fatto che l'iniziale sia maiuscola o minuscola. Inserire tale pipeline al posto del commento
INSERISCI CODICE QUI
.
Soluzione
La soluzione potrebbe essere la seguente:
import java.util.*; import java.util.stream.*; public class Esercizio14V { public static void main(String args[]) { List<String> stringList = getStringList(); Map<String, List<String>> map = stringList.stream().collect(Collectors.groupingBy( s -> (""+s.charAt(0)).toLowerCase())); System.out.println(map); } public static List<String> getStringList() { String stringa ="I ragazzi che si amano si baciano in piedi " + "Contro le porte della notte " + "E i passanti che passano li segnano a dito " + "Ma i ragazzi che si amano " + "Non ci sono per nessuno " + "Ed è la loro ombra soltanto " + "Che trema nella notte " + "Stimolando la rabbia dei passanti " + "La loro rabbia il loro disprezzo le risa la loro invidia " + "I ragazzi che si amano non ci sono per nessuno " + "Essi sono altrove molto più lontano della notte " + "Molto più in alto del giorno " + "Nell'abbagliante splendore del loro primo amore "; String[] stringhe = stringa.split(" "); return Arrays.asList(stringhe); } }
Si noti che laFunction
passata al metodogroupingBy
, ritorna il primo carattere, che viene "sommato" ad una stringa vuota per essere tramutato in stringa, per poi essere reso minuscolo per evitare di avere distinzioni tra maiuscole e minuscole. Purtroppo l'output non è molto leggibile (vedi esercizio successivo):
{a=[amano, a, amano, amano, altrove, alto, amore], b=[baciano], c=[che, Contro, che, che, ci, Che, che, ci], d=[della, dito, dei, disprezzo, della, del, del], e=[E, Ed, Essi], g=[giorno], è=[è], i=[I, in, i, i, il, invidia, I, in], l=[le, li, la, loro, la, La, loro, loro, le, la, loro, lontano, loro], m=[Ma, molto, Molto], n=[notte, Non, nessuno, nella, notte, non, nessuno, notte, Nell'abbagliante], o=[ombra], p=[piedi, porte, passanti, passano, per, passanti, per, più, più, primo], r=[ragazzi, ragazzi, rabbia, rabbia, risa, ragazzi], s=[si, si, segnano, si, sono, soltanto, Stimolando, si, sono, sono, splendore], t=[trema]}
-
Esercizio 14.z)
Partendo dal risultato dell'esercizio 14.v, sostituire all'istruzione di stampa:
System.out.println(map);
con una semplice pipeline che stampi riga per riga il contenuto della mappa.
Soluzione
La soluzione potrebbe essere la seguente:
import java.util.*; import java.util.stream.*; public class Esercizio14Z { public static void main(String args[]) { List<String> stringList = getStringList(); Map<String, List<String>> map = stringList.stream().collect( Collectors.groupingBy(s -> (""+s.charAt(0)).toLowerCase())); map.entrySet().stream().forEach(System.out::println); } public static List<String> getStringList() { String stringa ="I ragazzi che si amano si baciano in piedi " + "Contro le porte della notte " + "E i passanti che passano li segnano a dito " + "Ma i ragazzi che si amano " + "Non ci sono per nessuno " + "Ed è la loro ombra soltanto " + "Che trema nella notte " + "Stimolando la rabbia dei passanti " + "La loro rabbia il loro disprezzo le risa la loro invidia " + "I ragazzi che si amano non ci sono per nessuno " + "Essi sono altrove molto più lontano della notte " + "Molto più in alto del giorno " + "Nell'abbagliante splendore del loro primo amore "; String[] stringhe = stringa.split(" "); return Arrays.asList(stringhe); } }
L'output è decisamente più chiaro:
a=[amano, a, amano, amano, altrove, alto, amore] b=[baciano] c=[che, Contro, che, che, ci, Che, che, ci] d=[della, dito, dei, disprezzo, della, del, del] e=[E, Ed, Essi] g=[giorno] è=[è] i=[I, in, i, i, il, invidia, I, in] l=[le, li, la, loro, la, La, loro, loro, le, la, loro, lontano, loro] m=[Ma, molto, Molto] n=[notte, Non, nessuno, nella, notte, non, nessuno, notte, Nell'abbagliante] o=[ombra] p=[piedi, porte, passanti, passano, per, passanti, per, più, più, primo] r=[ragazzi, ragazzi, rabbia, rabbia, risa, ragazzi] s=[si, si, segnano, si, sono, soltanto, Stimolando, si, sono, sono, splendore] t=[trema]
-
Esercizio 14.aa)
Quali delle seguenti affermazioni sono corrette?
1. La classeHashMap
estendeHashtable
.
2. La classeHashtable
non è thread-safe.
3. La classeHashtable
estendeProperties
.
4.Enumeration
è stata deprecata da quando sono state introdotte le enumerazioni e la parola chiaveenum
in Java 5.
5. L'interfacciaEnumeration
ha gli stessi metodi dell'interfacciaIterator
.
6. La classeVector
implementaList
.
7. La classeVector
non è thread-safe.
8. La classeVector
non è generica.
9. In generale la classeVector
, essendo sincronizzata, offre prestazioni superiori rispetto ad unArrayList
.
10. La classeVector
è deprecata.
Soluzione
Solo l’affermazione 6 è corretta.