Il team Java ha svolto moltissimo lavoro rimuovendo gli ostacoli alla programmazione funzionale in Java 8. In particolare, le modifiche alle raccolte java.util svolgono un ottimo lavoro nel concatenare le trasformazioni in operazioni in streaming molto veloce. Considerando quanto sono stati bravi a fare un lavoro aggiungendo funzioni e metodi funzionali di prima classe sulle collezioni, perché non sono riusciti a fornire collezioni immutabili o persino interfacce di raccolta immutabili?
Senza modificare alcun codice esistente, il team Java potrebbe in qualsiasi momento aggiungere interfacce immutabili uguali a quelle mutabili, meno i metodi "set" e fare in modo che le interfacce esistenti si estendano da esse, in questo modo:
ImmutableIterable
____________/ |
/ |
Iterable ImmutableCollection
| _______/ / \ \___________
| / / \ \
Collection ImmutableList ImmutableSet ImmutableMap ...
\ \ \_________|______________|__________ |
\ \___________|____________ | \ |
\___________ | \ | \ |
List Set Map ...
Certo, operazioni come List.add () e Map.put () attualmente restituiscono un valore booleano o precedente per la chiave data per indicare se l'operazione ha avuto esito positivo o negativo. Le raccolte immutabili dovrebbero trattare tali metodi come fabbriche e restituire una nuova raccolta contenente l'elemento aggiunto, che è incompatibile con la firma corrente. Ma questo potrebbe essere aggirato usando un nome di metodo diverso come ImmutableList.append () o .addAt () e ImmutableMap.putEntry (). La verbosità risultante sarebbe più che compensata dai vantaggi di lavorare con raccolte immutabili, e il sistema dei tipi impedirebbe errori nel chiamare il metodo sbagliato. Nel tempo, i vecchi metodi potrebbero essere deprecati.
Vittorie di collezioni immutabili:
- Semplicità: il ragionamento sul codice è più semplice quando i dati sottostanti non cambiano.
- Documentazione: se un metodo accetta un'interfaccia di raccolta immutabile, sai che non modificherà quella raccolta. Se un metodo restituisce una raccolta immutabile, sai che non puoi modificarlo.
- Concorrenza: le raccolte immutabili possono essere condivise in modo sicuro tra thread.
Come qualcuno che ha assaggiato le lingue che assumono immutabilità, è molto difficile tornare nel selvaggio West di mutazione dilagante. Le raccolte di Clojure (astrazione di sequenza) hanno già tutto ciò che le raccolte di Java 8 forniscono, oltre all'immutabilità (anche se forse usano memoria e tempo extra a causa di liste collegate sincronizzate invece di flussi). Scala ha collezioni sia mutabili sia immutabili con una serie completa di operazioni, e sebbene quelle operazioni siano entusiaste, chiamare .iterator offre una visione pigra (e ci sono altri modi per valutarle pigramente). Non vedo come Java possa continuare a competere senza raccolte immutabili.
Qualcuno può indicarmi la storia o la discussione su questo? Sicuramente è pubblico da qualche parte.
const
raccolte
Collections.unmodifiable*()
. ma non trattarli come immutabili quando non lo sono
ImmutableList
in quel diagramma, le persone possono passare in un mutevole List
? No, questa è una molto brutta violazione della SPA.