TDJoe
TDJoe

Reputation: 1398

Does guava have a method for turning an iterable into a map of unique types?

I could not find a method in guava that converts a Collection (or Iterator/Iterable) to a Map, something like the following (wildcards omitted for clarity):

public static <T, K, V> Map<K,V> collectionSplitter(Collection<T> source, Function<T,K> kProducer, Function<T,V> vProducer){
    Map<K,V> map = Maps.newHashMap();
    for(T t : source){
        map.put(kProducer.apply(t), vProducer.apply(t));
    }
    return map;
}

Is any existing method that does this? The closest I could find is Splitter.keyValueSplitter(), if T is a String.

Upvotes: 10

Views: 4541

Answers (3)

molok
molok

Reputation: 1631

You can do it with the java8 stream api

Map<Object, Object> map = StreamSupport.stream(iterable.spliterator(), false)
                         .collect(Collectors.toMap(obj -> toKey(obj), 
                                                   obj -> toValue(obj)));

Upvotes: 0

Etienne Neveu
Etienne Neveu

Reputation: 12692

As Jon Skeet mentioned, Maps.uniqueIndex is currently the closest thing to what you are looking for.

There are also a few requests for what you are looking for in the issue tracker, which you might want to "star" if you are interested in the suggested function:

http://code.google.com/p/guava-libraries/issues/detail?id=56

http://code.google.com/p/guava-libraries/issues/detail?id=460

http://code.google.com/p/guava-libraries/issues/detail?id=679

http://code.google.com/p/guava-libraries/issues/detail?id=718

Upvotes: 1

Jon Skeet
Jon Skeet

Reputation: 1503469

The closest I'm aware of is Maps.uniqueIndex - that does the key side, but not the value side... is that close enough?

You could potentially use:

Map<K, V> map = Maps.transformValues(Maps.uniqueIndex(source, kProducer),
                                     vProducer);

Slightly awkward, but it would get the job done, I think...

Upvotes: 13

Related Questions