Sto cercando di rielaborare alcuni dei miei metodi per renderli più concisi utilizzando Java 8, le cui nuove funzionalità sto cercando di assorbire lentamente.Riprogettazione del metodo per utilizzare Java 8 Map.computeIfAbsent() con eccezione generata
È un metodo con lo scopo di aggiungere uno value
a Map<Key, Set<Value>>
. Esistono tre possibilità:
- La chiave non esiste: viene aggiunta e ad essa è associata una nuova serie contenente il valore.
- La chiave esiste: il valore viene aggiunto al set esistente. Si noti che un set non sarà mai
null
, perché ho alcune condizioni preliminari per affrontarlo. - La chiave esiste e il valore è già contenuto nel set: viene emesso un numero
IllegalArgumentException
.
Il codice che implementa questo comportamento è la seguente, e non fa uso di Java 8 caratteristiche:
public void addValue(Key key, Value value) {
// irrelevant preconditions...
Set<Value> valuesForKey = myMap.get(key);
if (valuesForKey != null && valuesForKey.contains(value))
throw new IllegalArgumentException("Association exists already");
if (valuesForKey == null)
myMap.put(key, new HashSet<Value>(Arrays.asList(value)));
else
valuesForKey.add(value);
}
Vorrei ridurre questo codice utilizzando Java 8 metodi come computeIfAbsent.
potessi riassumere l'ultimo if-else
blocco, ma non posso andare oltre la ridondanza del valore impostato al quale key
mappe ad avere già in recuperati Nell'effettuare i controlli di presupposto.
public void addValue(Key key, Value value) {
// irrelevant preconditions...
Set<Value> valuesForKey = myMap.get(key);
if (valuesForKey != null && valuesForKey.contains(value))
throw new IllegalArgumentException("Association exists already");
myMap.computeIfAbsent(key, v -> new HashSet<Value>()).add(value);
}
C'è comunque una possibilità di unire tutto ciò in un'unica istruzione?
Mentre si può certamente fare in questo modo, si dovrebbe prendere in considerazione l'uso di un 'Multimap' (ad esempio da Guava). Avere una 'Mappa>' o 'Mappa >' è nel 99% dei casi d'uso un odore di design. –
Landei
@Landei, Secondo me non è proprio "odore di codice" dal momento che JDK non ha un multiset e uno potrebbe non voler inserire un'intera libreria solo per quell'unico utilizzo. È la soluzione più semplice disponibile in tali circostanze e i metodi 'compute *' e 'merge' del CHM rendono la giocoleria di quelle cose abbastanza dirette. – the8472
A mio parere, le raccolte JDK sono in uno stato pietoso (ad esempio mancano collezioni immutabili utilizzabili) e io uso librerie come Guava per quasi tutti i progetti. Ho fatto l'esperienza che una volta che hai importato una lib come quella, troverai sempre più posti dove è utile. – Landei