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,ListeSortedSetsono interfacce e non possono essere istanziate.
2. UnSetè una collezione ordinata di oggetti; unaListnon 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 unaHashtableperché non è sincronizzata.
6. UnaHashMapè più performante rispetto ad unTreeMapma quest'ultima, essendo un'implementazione diSortedMap, gestisce l'ordinamento.
7.HashSetè più performante rispetto aTreeSetma non gestisce l'ordinamento.
8.IteratoredEnumerationhanno lo stesso ruolo ma quest'ultima permette durante le iterazioni di rimuovere anche elementi.
9.ArrayListha prestazioni migliori rispetto aVectorperché 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 metodojoiningdiStreampermette di concatenare stringhe con dei separatori di tipo stringa.
8. La classeDoubleSummaryStatisticsè un particolare stream.
9. Il metodoparallelStreamritorna 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 dichiaratafinale quindi non estendibile).
6. Falso, sono operazioni terminali.
7. Falso, il metodojoiningappartiene 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 metodoaddnon è 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'ArrayListdefinito nella classeMappaIncrementalecon unSetRobustoabbiamo 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 classeMappaIncrementalee riscriviamo il metodoaddcon 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
equalsehashcode. 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
Cittaaggiungiamo 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 classeTestStreamsinvece 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 cicloformigliorato può in ogni caso sostituire un ciclofor.
2. Il cicloformigliorato può essere utilizzato con gli array e con le classi che implementanoIterable.
3. Il cicloformigliorato sostituisce l'utilizzo diIterator.
4. Il cicloformigliorato non può sfruttare correttamente i metodi diIterator.
5. In un cicloformigliorato 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
HashMapnon estendeCollection, e quindi non si può assegnare un reference di tipoCollectionad 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'interfacciaIterabledichiara il metodoforEach.
2.IteratorestendeIterable.
3.Iteratordefinisce il metodoforEachRemaining.
4.Collectionimplementa l'interfacciaIterable.
Soluzione
Le risposte corrette sono le numero 1 e 3.
Iteratornon estendeIterable, quindi l'affermazione 2 è non corretta. Nel caso dell'affermazione 4 l'affermazione sarebbe stata corretta se fosse stata:Collectionestende l'interfacciaIterable. Infatti siaCollectioncheIterablesono 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. UnaCollectionpuò essere trasformata in un array invocando il metodotoArraydefinito nella classeArrays.
3. Un array può essere trasformato in unaCollectionmediante il metodotoCollectiondella classeArrays.
4.Collectiondefinisce 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 metodotoCollectionnella 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 metodoaddnella listalist, e poi con il metodosetviene sovrascritto la stringa@con la stringa$. I successivi cicli stampano gli elementi della lista ciclando con unListIteratorprima in avanti e poi all'indietro. -
Esercizio 14.n)
Si crei un semplice programma che definisca un
ArrayListdi 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 diSetnon può ordinare i suoi elementi.
2. Un'implementazione diSetnon ammette più di un elementonull.
3. L'interfacciaSetè estesa daSortedSet.
4. L'implementazioneHashSetnon è thread safe.
Soluzione
Tutte le affermazioni sono corrette tranne la numero 1. Infatti essendo
Setestesa daSortedSet(vedi affermazione numero 3), le implementazioni diSortedSetcomeTreeSetsaranno ordinate ("sorted" in inglese significa "ordinato"). La numero 2 è vera proprio in virtù del fatto che qualsiasiSetnon 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 diListnon ammette elementinull.
3. Un reference di tipoListpuò diventare thread safe se gli viene assegnato
un oggetto di tipoListche viene ritornato dal metodosynchronizedList.
4. Per eliminare gli elementi duplicati da una lista, basta riempire unSetcon 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 staticoofdell'interfacciaListintrodotto 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 staticoofdell'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 metodoofNullablerestituisce un oggettoOptionalche fa da wrapper all'oggetto passato in input.
3.orElseThrowè un metodo diOptionalche restituisce un oggettoOptionalo lancia un'eccezione che può essere specificata in input, nel caso l'oggetto "wrappato" sianull.
4.findFirstè un metodo diOptionalche restituisce un oggettoOptionalonull, 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 laFunctionpassata 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 classeHashMapestendeHashtable.
2. La classeHashtablenon è thread-safe.
3. La classeHashtableestendeProperties.
4.Enumerationè stata deprecata da quando sono state introdotte le enumerazioni e la parola chiaveenumin Java 5.
5. L'interfacciaEnumerationha gli stessi metodi dell'interfacciaIterator.
6. La classeVectorimplementaList.
7. La classeVectornon è thread-safe.
8. La classeVectornon è generica.
9. In generale la classeVector, essendo sincronizzata, offre prestazioni superiori rispetto ad unArrayList.
10. La classeVectorè deprecata.
Soluzione
Solo l’affermazione 6 è corretta.