Reputation: 92150
This question is kind of already posted here: How to convert Map<String, String> to Map<Long, String> using guava
I think the answer of CollinD is appropriate:
All of Guava's methods for transforming and filtering produce lazy results... the function/predicate is only applied when needed as the object is used. They don't create copies. Because of that, though, a transformation can easily break the requirements of a
Set
.Let's say, for example, you have a
Map<String, String>
that contains both "1" and "01" as keys. They are both distinctString
s, and so theMap
can legally contain both as keys. If you transform them usingLong.valueOf(String)
, though, they both map to the value1
. They are no longer distinct keys. This isn't going to break anything if you create a copy of the map and add the entries, because any duplicate keys will overwrite the previous entry for that key. A lazily transformedMap
, though, would have no way of enforcing unique keys and would therefore break the contract of aMap
.
This is true, but actually I don't understand why it is not done because:
When the key transformation happen, if 2 keys are "merged", a runtime exception could be raised, or we could pass a flag to indicate to Guava to take any value of the multiple possible values for the newly computed key (failfast/failsafe possibilities)
We could have a Maps.transformKeys which produces a Multimap
Is there a drawback I don't see in doing such things?
Upvotes: 12
Views: 8365
Reputation: 14276
As @CollinD suggests, there's no way to do this in a lazy way. To implement get
, you have to convert all the keys with your transformation function (to ensure any duplicates are discovered).
So applying Function<K,NewK>
to Map<K,V>
is out.
You could safely apply Function<NewK,K>
to the map:
V value = innerMap.get( fn.apply(newK) );
I don't see a Guava shorthand for that--it may just not be useful enough. You could get similar results with:
Function<NewK,V> newFn = Functions.compose(Functions.forMap(map), fn);
Upvotes: 8