12

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 distinct Strings, and so the Map can legally contain both as keys. If you transform them using Long.valueOf(String), though, they both map to the value 1. 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 transformed Map, though, would have no way of enforcing unique keys and would therefore break the contract of a Map.

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?

Community
  • 1
  • 1
Sebastien Lorber
  • 89,644
  • 67
  • 288
  • 419

1 Answers1

8

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);
Michael Brewer-Davis
  • 14,018
  • 5
  • 37
  • 49