Ho sperimentato un comportamento TreeMap davvero spettrale e ho avuto qualche problema a restringere un piccolo caso di test, quindi portami con me.TreeMap put() cancella silenziosamente altre voci?
Voglio leggere un gran numero di coppie chiave-valore in una mappa, da un file fornito in fase di esecuzione. Sto usando una classe di chiavi personalizzata. Più tardi, quando vado a ritirare le voci, trovo che uno o più di essi manchino. Usando un debugger e alcuni casi di test, ho determinato che la voce mancante (i) sta scomparendo definitivamente durante la fase di lettura, ma non sono sicuro di cosa lo stia causando.
In sostanza:
Map<MyKey,Double> map = new TreeMap<MyKey,Double>();
map.put(key1,value1);
// ... put another ~500 entries into the map ...
assertTrue(map.containsKey(key1)); // passes
if (!map.containsKey(keyN)) {
map.put(keyN, valueN); // this code executes
}
assertTrue(map.containsKey(key1)); // FAILS
... Quindi, in sostanza, l'aggiunta di una nuova chiave per la mappa provoca una voce non correlato a cadere fuori di esso.
- Se ho appena aggiungo key1 e Keyn solo, chiave1 rimane nella mappa - i successivi 500 voci sono in qualche modo importanti
- Se rimuovo uno o due tasti arbitrarie da 2 .. (N-1), key1 è ancora avviato quando keyN è aggiunto
- Se rimuovo un ampio intervallo di chiavi da 2 .. (N-1), la chiave1 rimane quando keyN viene aggiunto, ma cade quando (say) viene aggiunto keyQ, ~ 300 chiavi più in basso sulla linea
- Sfortunatamente la dimensione della mappa quando keyN kick out key1 è non uguale alla dimensione della mappa quando keyQ kicking key1, quindi è probab non è un problema di dimensioni limitate
- Se utilizzo una HashMap, la chiave 1 rimane nella mappa
- Classe chiave personalizzata MyKey utilizza la stessa logica per Comparable, equals e hashCode.
Inizialmente utilizzavo TreeMap perché prevedo di utilizzare set di dati di grandi dimensioni e TreeMap è un po 'più efficiente in termini di memoria. HashMap sarà un'alternativa eccellente, ma è ancora allarmante vedere TreeMap comportarsi in questo modo - qualcuno ha pensieri su cosa sta succedendo qui?
D'accordo con Steve Kuo. Commenta il tuo confronto per/equals/hashCode implementazione ed esegui nuovamente il tuo test e vedi se ottieni lo stesso problema. – digitaljoel