Suppongo tu intenda Map.put
- perché non c'è Map.add
. Ma anche se avessero lo stesso nome, questi metodi si comportano in modo abbastanza diverso da rendere privi di significato qualsiasi tentativo di unificare la loro interfaccia.
Guarda come viene restituito il % di ritorno diCollection.add
il documento del valore è formulato:
true if this collection changed as a result of the call
Ora, l'unica ragione valida per la raccolta di non cambiare è se si tratta di un set e l'elemento è già lì (qualsiasi altro motivo deve essere lanciato), ma è stato scelto quel testo perché ha senso per tutti collezioni, senza dover creare clausole speciali per set e non-set.
Ma ha senso per le mappe? Considera questo:
HashMap<Integer, Integer> map = new HashMap<Integer, Integer>();
map.put(1, 2);
map.put(2, 2);
/*case 1*/ map.put(1, 1); // value changed - would have returned 'true'
/*case 2*/ map.put(2, 2); // nothing changed - would have returned 'false'
/*case 3*/ map.put(3, 3); // key-value pair added - would have returned 'true'
I casi 1 e 3 restituiscono entrambi true
, ma sono molto diversi: uno sovrascrive una voce e l'altra ne aggiunge una nuova. Quindi forse il caso 1 avrebbe dovuto restituire false
? Ma poi sarebbe stato lo stesso del caso 2, anche se uno sta cambiando la mappa e l'altro no ...
Quindi, copiare il comportamento di Collection.add
in Map.put
non ha senso. Che ne dici di copiare il comportamento di Map.put
in Collection.add
? Cosa accadrebbe se avessimo Collection.add
per restituire il vecchio valore?
Vedo diversi problemi con questo:
- Rende l'interfaccia più complicata - ora ha bisogno di dare definizioni diverse per mappe e insiemi, o fare una definizione più complessa (es. - "se l'elemento non è stato aggiunto perché era già lì, restituire l'oggetto che era già lì ". Ugh ...)
- Non è molto utile. Hai già l'elemento già presente nella raccolta: l'hai appena inviato come argomento a
add
!
-
Che cosa succede se abbiamo un TreeSet
con un comparatore personalizzato?
TreeSet<Integer> treeSet = new TreeSet<Integer>((a, b) -> Integer.compare(a % 10, b % 10));
treeSet.add(11);
treeSet.add(21); // should this return '11' or '21'?
Questo non è un problema con Map
, perché sta cercando dalla chiave, ed è già obbligato a definire ciò che ottieni quando richiedi quella chiave.
-
Costringe la collezione a recuperare effettivamente il valore. Che cosa succede se l'implementazione di Collection
è un filtro bloom? Ora deve effettivamente cercare l'oggetto invece di fare una rapida corrispondenza hash. Cosa succede se si tratta di un wrapper attorno a una tabella di database? Ora deve creare un oggetto che hai già!
Ovviamente, Map
avrebbe un problema simile - ma almeno lì il vecchio valore è importante, perché non sai cosa sia e sparirà. Ma con Collection
? È tutto a costo zero e nessun guadagno ...