Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why Guava does not provide a way to transform map keys

Tags:

java

guava

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?

like image 566
Sebastien Lorber Avatar asked Dec 21 '12 14:12

Sebastien Lorber


People also ask

Can we convert map to string in Java?

Use Object#toString() . String string = map. toString();

Can we convert Map to String?

We can convert a map to a string in java using two array lists. In this, we first fill the map with the keys. Then, we will use keySet() method for returning the keys in the map, and values() method for returning the value present in the map to the ArrayList constructor parameter.

What is guava Multimap?

A Multimap is a new collection type that is found in Google's Guava library for Java. A Multimap can store more than one value against a key. Both the keys and the values are stored in a collection, and considered to be alternates for Map<K, List<V>> or Map<K, Set<V>> (standard JDK Collections Framework).


1 Answers

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);
like image 149
Michael Brewer-Davis Avatar answered Sep 22 '22 11:09

Michael Brewer-Davis