Given a multimap, I need to combine the entries with respect to their functional dependencies.
I might have misused the term functional dependency. What I mean is:
If I have three entries of multimap:
a -> b c d
b -> c e f
g -> f h i
I want to combine them as
a -> c e d f
g -> h i
e
and f
go to a
because b
is a value of a
and c, e, f
are values of b
.
h
and i
go to g
because neither g
nor h
are values of a
.
f
does not go to a
because it appears in values of a
(priority is ascending).
Here is the code I've written, which gives ConcurrentModificationError
:
Multimap<Integer, Integer> map = TreeMultimap.create();
Multimap<Integer, Integer> map2 = TreeMultimap.create();
map.put(0, 1);
map.put(0, 3);
map.put(0, 4);
map.put(1, 3);
map.put(1, 4);
map.put(1, 6);
map.put(3, 7);
map.put(3, 9);
map.put(3, 10);
map.put(2, 7);
map.put(2, 8);
map.put(2, 9);
System.out.println(map);
for(int i : map.keySet())
{
for(int j : map.get(i))
{
if(map.containsKey(j))
{
Collection<Integer> list = map.get(j);
map2.putAll(i, map.get(j));
map.values().removeAll(list);
}
}
if(!map.values().contains(i))
map2.putAll(i, map.get(i));
}
System.out.println(map2);
The output is:
{0=[1, 3, 4], 1=[3, 4, 6], 2=[7, 8, 9], 3=[7, 9, 10]}
Exception in thread "main" java.util.ConcurrentModificationException
at java.util.TreeMap$PrivateEntryIterator.nextEntry(Unknown Source)
at java.util.TreeMap$KeyIterator.next(Unknown Source)
at com.google.common.collect.AbstractMapBasedMultimap$WrappedCollection$WrappedIterator.next(AbstractMapBasedMultimap.java:486)
at test.Test.main(Test.java:68)
However, I expect it to be:
{0=[1, 3, 4], 1=[3, 4, 6], 2=[7, 8, 9], 3=[7, 9, 10]}
{0=[1, 3, 4, 6, 7, 9, 10], 2=[8]}
A key is always mapped to three values.
You can't iterate over map, and modify it at the same time. The easiest thing you can do to fix your code, is to create a new map as you go through the input rather than modifying the existing one in place.