I just posted an updated version of my util
library of extensions to Java Collections in the course of which I added a ListMap
interface to replace UnionMap
and an implementation, ArrayHashListMap
.
If one were to write read-only Map
implementations, the procedure is straight-forward and well-documented in the Javadocs for Map
. However, writing a modifiable map is much more of an undertaking.
Consider all the places that "modifiability" can be leaked:
entrySet()
- This is burdensome as the
Set
has to provide modifiable operations which effect the originalMap
and all methods ofSet
which themselves return modifiable collections or iterators need to tie back to the originalMap
all the way down toMap.Entry
. keySet()
- The same remarks for
entrySet()
apply tokeySet()
(exceptionMap.Entry
). values()
- Similarly for
values()
although it is aCollection
rather than aSet
, a distinction of very little. layers()
- A method particular to
ListMap
, it returns a list of maps which comprise thePATH
-like layers which are collapsed to present a singleMap
view.
What did I do in face of this? I introduced a new interface, Refreshing
(would Refreshable
have been better?), which has one method, void refresh()
, implemented versions of Map
List
, Set
and Iterator
which take a Refreshing
object to signal after modifiable operations complete, and extended AbstractMap
to return refreshing versions of collection classes for each of the possible points where modifiability leaks. You can see the result in ListMap
and ArrayHashListMap
.
Thank goodness for mock objects and unit tests!
2 comments:
Ick. The views into the map really ought not to modify the underlying contents of a Map. Its not obvious enough what it means to remove items from the "values" collection, or the "keySet" set.
Agreed, and yet this is what HashMap does AFAICT.
Post a Comment