Reputation: 170735
If I want to create a new Multimap
with simple defaults, I curently need to do something like:
private final Multimap<Key, Value> providersToClasses = Multimaps
.newListMultimap(
new HashMap<Key, Collection<Value>>(),
new Supplier<List<Value>>() {
@Override
public List<Value> get() {
return Lists.newArrayList();
}
});
...because Java can't infer the correct types if Maps.newHashMap
is used for the backing map. Of course, this can be refactored into a separate method, but is there already a way to write it more concisely?
Upvotes: 46
Views: 52221
Reputation: 6483
The Guava documentation states that the create
method advocated by some other answers "will soon be deprecated" in favour of the different forms presented below, and should therefore be avoided.
From Guava 21.0 onwards, the recommended way of creating a Multimap
object where values are stored in ArrayList
collections is the following:
MultimapBuilder.hashKeys().arrayListValues().build();
You can also use parameters if you want to specify the expected number of keys in your map and the expected number of values per key:
MultimapBuilder.hashKeys(expectedKeys).arrayListValues(expectedValuesPerKey).build();
Finally, you can create a new Multimap
from an existing one using this construct:
MultimapBuilder.hashKeys().arrayListValues().build(multimap);
If you want to use data structures other than ArrayLists
in your Multimap
, you can replace the call to arrayListValues()
by a number of other ones, listed here.
Upvotes: 15
Reputation: 996
Here is compact solution:
Multimap<Integer, String> multi = HashMultimap.create();
Upvotes: 6
Reputation: 12112
In Java 8 this is much nicer, for all kinds of multimaps. This is for two reasons:
HashMap
contructor.ArrayList
factory.It looks like this:
Multimap<Key, Value> providersToClasses =
Multimaps.newListMultimap(new HashMap<>(), ArrayList::new);
Upvotes: 4
Reputation: 7844
I run into this problem when writing clients and building up maps of query params. A nice succinct pattern I like for constructing multi-maps is to use ImmutableMultiMap#builder
Multimap<String, String> queryParams =
ImmutableMultimap.<String, String>builder()
.put("key-1", "value-1")
.put("key-1", "value-2")
.build();
Upvotes: 27
Reputation: 1974
Why aren't you using ArrayListMultimap.create()
for such a simple case? It's the default way to create the simple HashMap/ArrayList that is probably the most common used multimap.
Upvotes: 62
Reputation: 11705
To answer the original type inference problem, though, you can also specify the generic types on a static method using Maps.<Key, Collection<Value>>newHashMap()
, but it's certainly not more concise than new HashMap<Key, Collection<Value>>()
(it may be more consistent).
Upvotes: 2