Si, esiste un modo decisamente migliore!
Devi usare il design pattern (
https://sourcemaking.com/design_pattern) OBSERVER/OBSERVED.
Fondamentalmente: la tua Mappa non e' una semplice mappa, ma un oggetto che contiene una mappa, che si comporta come una mappa, ma che ogni volta che succede qualcosa alla mappa interna, viene generato un EVENTO (aggiunto un elemento alla mappa, rimosso un elemento dalla mappa, ..)
Ora, chiunque sia interessato a sapere che cosa succede nella mappa, si REGISTRA come LISTENER per uno o piu' eventi che il tuo superoggetto Mappa puo' generare.
Ed il gioco e' fatto.
A descriverlo e' complicato, ad implementarlo, banale.
Ma, ovviamente, serve avere chiaro i concetti coinvolti
Piu' in generale, la definizione di oggetto, nella programmazione ad oggetti, e' sempre stata fatta in modo parziale:
un oggetto ha uno stato (i membri di istanza) ed una serie di operazioni disponibili (i metodi)
I problema dei metodi e che questi vengono usati da qualcun altro (lasciamo stare il fatto che l'oggetto puo' usare i suoi stessi metodi).
Messa cosi', se non c'e' nessuno che interagisce con l'oggetto, questo rimane assolutamente silente (e non serve a niente).
Manca la parte:
l'oggetto emette, di sua iniziativa, degli EVENTI.
Questo fa si che l'oggetto possa fare qualcosa anche senza che nessuno gli rompa le scatole.
Pero' chi vuole, puo' REGISTRARSI per sapere che cosa l'oggetto sta' combinando.