Useful Map related method.

0 views
Skip to first unread message

Sean Parsons

unread,
Aug 22, 2008, 7:54:43 AM8/22/08
to Google Collections Library - developer list
Internally we're using this method based off the back of the existing
Google Collections work and I've been given permission to share it in
the spirit of the library I guess you could say:

public static <K, V> void addAll(Map<K,V> destinationMap,
Iterable<V> source, Function<V, K> valueToKeyFunction)
{
Preconditions.checkArgument(destinationMap != null,
"Destination map cannot be null.");
Preconditions.checkArgument(source != null, "Iterable source
cannot be null.");
Preconditions.checkArgument(valueToKeyFunction != null, "Value
converting function cannot be null.");
destinationMap.putAll(Maps.uniqueIndex(source,
valueToKeyFunction));
//for (V value : iterable)
//{
// map.put(valueToKeyFunction.apply(value), value);
//}
}

The commented out code at the bottom is the original version, I've not
done any particular performance testing. But it seems like a
reasonable assumption that the two methods used in the current
revision could offer some performance benefits over pure iteration.

Sean.

Jared Levy

unread,
Aug 22, 2008, 12:26:23 PM8/22/08
to Sean Parsons, Google Collections Library - developer list
Thanks for the suggestion. It's similar to our Maps.uniqueIndex() method.

uniqueIndex

public static <K,V> ImmutableMap<K,V> uniqueIndex(Iterable<V> values,
Function<? super V,K> keyFunction)
Returns an immutable map for which the Map.values() are the given elements in the given order, and each key is the product of invoking a supplied function on its corresponding value.

Parameters:
values - the values to use when constructing the Map
keyFunction - the function used to produce the key for each value
Returns:
a map mapping the result of evaluating the function keyFunction on each value in the input collection to that value
Throws:
IllegalArgumentException - if keyFunction produces the same key for more than one value in the input collection
NullPointerException - if any elements of values is null, or if keyFunction produces null for any value

http://google-collections.googlecode.com/svn/trunk/javadoc/com/google/common/collect/Maps.html#uniqueIndex(java.lang.Iterable,%20com.google.common.base.Function)

Sean Parsons

unread,
Aug 22, 2008, 6:43:48 PM8/22/08
to Google Collections Library - developer list
On Aug 22, 5:26 pm, "Jared Levy" <jared.l.l...@gmail.com> wrote:
> Thanks for the suggestion. It's similar to our Maps.uniqueIndex() method.

Well it does use it in the implementation supplied! :)

Sean Parsons

unread,
Aug 22, 2008, 6:50:19 PM8/22/08
to Google Collections Library - developer list
This method came about because in our own use of the GCL we nearly
always kept the Function implementations as static final instances
usually used in calls to the transform methods on Iterables and the
suchlike. So this ended up making populating a Map instance from an
Iterable a simple one liner. That's been our use case for it, anyway.

Jared Levy

unread,
Aug 22, 2008, 7:00:24 PM8/22/08
to Sean Parsons, Google Collections Library - developer list
Sorry I didn't look at your code sample carefully.

In general, we tend not to include shorter methods, like the one you're proposing, in the library unless we believe they'll be heavily used. The more methods a library contains, the more difficult it is to find the particular method you're interested in. Your example is a single statement if you ignore the preconditions.

FYI, there is one behavioral difference between uniqueIndex and the commented-out code. If the function maps two source values to the same output, uniqueIndex fails but the commented code would succeed.

Sean Parsons

unread,
Aug 22, 2008, 7:42:42 PM8/22/08
to Google Collections Library - developer list
I have to admit after putting it forward I did think the same thing
you mentioned about it being a one-liner!

In the cases where this is being used I think we need the benefits of
that uniqueIndex call against the destination Map as well, so I may be
revisiting it to make sure that it does not overwrite existing
entries. I can see the method call being changed to uniquePutAll now!

But anyway thanks for the responses and please convey our thanks to
those people responsible for the GCL as even in the couple of weeks
we've been using them, they have been of enormous benefit to us.
Reply all
Reply to author
Forward
0 new messages