I have a Map
Map<Integer, List<Object>> entireData;
Now to this I'm adding some data using putAll like
entireData.putAll(someData);
开发者_如何学JAVA
where someData returns Map<Integer, List<Object>>
Now, I have another line which says
entireData.putAll(someMoreData);
which also returns Map<Integer, List<Object>>
, but by doing this it over-writes the content of the existing entireData, how do I append?
First line of the Java Map Class Reference:
An object that maps keys to values. A map cannot contain duplicate keys; each key can map to at most one value.
You want a Multimap from Google Guava. Rewriting your example with Guava Multimap:
ListMultimap<Integer, Object> entireData = ArrayListMultimap.create();
entireData.get(key)
returns a List<Object>
. putAll
will not override old keys but will append the values of those keys to the existing values. This is also much nicer than dealing with initializing the List
instances yourself.
for (Integer key : someMoreData.keySet())
{
if (entireData.containsKey(key))
{
entireData.get(key).addAll(someMoreData.get(key));
}
else
{
entireData.put(key, someMoreData.get(key));
}
}
Keys are unique. If someMoreData
has a key same as already existing key in entireData
the value i.e. list of object will be overwritten.
However you can loop in someMoreData
and append for keys that exists in entireData
like
for(Integer key: someMoreData.keySet()){
if(entireData.get(key)!=null)
entireData.get(key).addAll(someMoreData.get(key));
else
entireData.put(key,someMoreData.get(key));
}
Per default, Java Maps map one key to one value, as trojanfoe writes. If that is not sufficient to your needs, you need a Multi-Map implementation (A Map that maps from a key to a collection of values).
The most popular versions can be found in two open source Frameworks, Google Guava and Apache Commons / Collections.
Guava Example:
final Multimap<Integer, String> mmap =
Multimaps.newSetMultimap(
Maps.<Integer, Collection<String>> newHashMap(),
new Supplier<Set<String>>(){
@Override
public Set<String> get(){
return Sets.newHashSet();
}
});
mmap.put(1, "foo");
mmap.put(1, "bar");
System.out.println(mmap.get(1));
Output:
[foo, bar]
Commons Collections Example:
final MultiMap mmap = new MultiHashMap();
mmap.put(1, "foo");
mmap.put(1, "bar");
System.out.println(mmap.get(1));
Output:
[foo, bar]
As you can see, the Commons Collections version is a lot simpler, but it's also less powerful, and in the current version it doesn't support Java 1.5 generics. So I'd go with Guava.
similar to willcodejavaforfood's no dependencies needed answer but using an entrySet instead for less HashMap retrievals.
public static <K,V> void appendMapBtoMapA(HashMap<K,List<V>> a, HashMap<K,List<V>> b) {
for (Map.Entry<K, List<V>> bEntry : b.entrySet()) {
if (a.containsKey(bEntry.getKey())) {
a.get(bEntry.getKey()).addAll(bEntry.getValue());
} else {
a.put(bEntry.getKey(), bEntry.getValue());
}
}
}
or Nishant's which drops a contains call and adds a null check but with entrySet
public static <K,V> void appendMapBtoMapA(HashMap<K,List<V>> a, HashMap<K,List<V>> b) {
for (Map.Entry<K, List<V>> bEntry : b.entrySet()) {
List<V> aValue = a.get(bEntry.getKey());
if (aValue != null) {
aValue.addAll(bEntry.getValue());
} else {
a.put(bEntry.getKey(), bEntry.getValue());
}
}
}
or with java 8
public static <K,V> void appendMapBtoMapA(HashMap<K,List<V>> a, HashMap<K,List<V>> b) {
for (Map.Entry<K, List<V>> bEntry : b.entrySet()) {
a.computeIfAbsent(
bEntry.getKey(),
k -> new LinkedList<>()
).addAll(bEntry.getValue());
}
}
精彩评论