Java setting values from a Map to a Set

I am trying to make a method that takes the first Map whose values are sets and a second empty Map whose values are Lists and fills the second Map with the same key/value Mappings as the first. The 2nd map will have every key in the 1st Map, but associated with it is a List of all the same elements that are in the Set it maps to. Use the ArrayList in the Second Map. Here is the method I got.

public static<K,E> void values(Map<K, Set<E>> ml, Map<K, List<E>> m2){
  for (Map.Entry<K, Set<E>> e; e < ml.size(); ? // I am not sure what to write here: a e.hasNext() or a
  // then i have to use a put method right?
  m2.put(e.getKey(), new ArrayList<E>(? )) // I don't know how to get the value, would it just be the same as e.getKey() or e.value

Can you tell me how you would do this? or if there is anything wrong? Thank you for your help

13.10.2009 23:26:12

I find while loops are better for iterating than for loops, but maybe it's just me :)

public static<K,E> void values(Map<K, Set<E>> m1, Map<K, List<E>> m2) {
    Iterator<K> iter = m1.keySet().iterator();
    while (iter.hasNext()) {
        K key =;
        Set<E> value = m1.get(key);
        m2.put(key, new ArrayList<E>(value));
13.10.2009 23:56:21
Thank you so much! So, the keySet would just put the values from m1 into the iterator right?
user189487 13.10.2009 23:41:08
Yes. Keyset gives you a set of all the m1 keys :) Alternatively you can use the entry set, which avoids calling get() for every key.
Spyder 13.10.2009 23:55:43

Not 100% exactly what you mean, but how about this:

public static<K,E> void values(Map<K, Set<E>> m1, Map<K, List<E>> m2)
    for(K key : m1.keySet())
        Set<E> source = m1.get(key);

        List<E> dest = m2.get(key);
        if(dest == null)
            dest = new ArrayList<E>();
            m2.put(key, dest);

13.10.2009 23:41:29
Thank you for the answer, but what is receiver?
user189487 13.10.2009 23:43:00
Whoops, I renamed 'receiver' to 'dest' but looks like I missed that line.
Outlaw Programmer 13.10.2009 23:45:27

2 options:

public static <K, E> void values(Map<K, Set<E>> m1, final Map<K, List<E>> m2) {
    if (m1 == null)
        throw new IllegalArgumentException("null map 1");
    if (m2 == null)
        throw new IllegalArgumentException("null map 2");

    for (Map.Entry<K, Set<E>> e : m1.entrySet()) {
        m2.put(e.getKey(), new ArrayList<E>(e.getValue()));

public static <K, E> Map<K, List<E>> values(Map<K, Set<E>> m) {
    if (m == null)
        throw new IllegalArgumentException("null map");

    Map<K, List<E>> m2 = new HashMap<K, List<E>>(Math.max(
            (int) (m.size() / 0.75f) + 1, 16), 0.75f);

    for (Map.Entry<K, Set<E>> e : m.entrySet()) {
        m2.put(e.getKey(), new ArrayList<E>(e.getValue()));

    return m2;
13.10.2009 23:55:05
Looks good but I think explicitly setting the initial capacity is a little overkill and might be confusing.
Outlaw Programmer 13.10.2009 23:58:37

I highly recommend using MultiMap for this, if you can. Google has a wonderful interface Multimap. There are two subinterfaces:

  • SetMultimap<K, V> which is equivalent to Map<K, Set<V>>
  • ListMultimap<K, V> which is equivalent to Map<K, List<V>>

The interfaces abstract away a lot of the array/list complexities, and the desired method would look like:

public static <K, E> void values(Multimap<K, E> m1, Multimap<K, E> m2) {

(Needless to say you won't need to have an extra method in the first place).

The interface allows simple insertion pattern

Multimap<String, String> map1 = HashMultimap.create();
map1.put("a", "first");
map1.put("a", "second");
map1.put("b", "third");

map1.get("a");  // --> returns ["first", "second"]
map1.get("b");  // --> returns ["third"]
map1.get("c");  // --> returns [], empty set =)
14.10.2009 00:11:16