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
Sethas to provide modifiable operations which effect the originalMapand all methods ofSetwhich themselves return modifiable collections or iterators need to tie back to the originalMapall the way down toMap.Entry. keySet()- The same remarks for
entrySet()apply tokeySet()(exceptionMap.Entry). values()- Similarly for
values()although it is aCollectionrather 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 singleMapview.
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