Sebastien Lorber
Sebastien Lorber

Reputation: 92150

Why Guava does not provide a way to transform map keys

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:

Is there a drawback I don't see in doing such things?

Upvotes: 12

Views: 8365

Answers (1)

Michael Brewer-Davis
Michael Brewer-Davis

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

Related Questions