【问题标题】:Java setting values from a Map to a Set从 Map 到 Set 的 Java 设置值
【发布时间】:2009-10-13 23:26:12
【问题描述】:

我正在尝试创建一个方法,该方法采用第一个值为集合的 Map 和第二个值为 Lists 的空 Map,并使用与第一个相同的键/值映射填充第二个 Map。第二个映射将具有第一个映射中的每个键,但与之关联的是一个列表,该列表包含它映射到的 Set 中的所有相同元素。在第二个地图中使用 ArrayList。这是我得到的方法。

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 e.next)
  // 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
}

你能告诉我你会怎么做吗?或者如果有什么问题? 谢谢你的帮助

【问题讨论】:

    标签: java map arraylist set


    【解决方案1】:

    不是 100% 完全是你的意思,但是这个怎么样:

    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);
            }
    
            dest.addAll(source);
        } 
    }
    

    【讨论】:

    • 谢谢你的回答,但是接收者是什么?
    • 糟糕,我将 'receiver' 重命名为 'dest' 但看起来我错过了那行。
    【解决方案2】:

    2 个选项:

    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;
    }
    

    【讨论】:

    • 看起来不错,但我认为明确设置初始容量有点矫枉过正,可能会造成混淆。
    【解决方案3】:

    我发现 while 循环比 for 循环更适合迭代,但也许只有我一个人 :)

    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 = iter.next();
            Set<E> value = m1.get(key);
            m2.put(key, new ArrayList<E>(value));
        }
    }
    

    【讨论】:

    • 非常感谢!那么,keySet 只会将 m1 中的值放入迭代器中,对吧?
    • 是的。 Keyset 为您提供了一组所有 m1 键 :) 或者,您可以使用条目集,这样可以避免为每个键调用 get()。
    【解决方案4】:

    如果可以的话,我强烈推荐使用 MultiMap。谷歌有一个很棒的界面Multimap。有两个子接口:

    • SetMultimap&lt;K, V&gt; 相当于 Map&lt;K, Set&lt;V&gt;&gt;
    • ListMultimap&lt;K, V&gt; 相当于 Map&lt;K, List&lt;V&gt;&gt;

    接口抽象了很多复杂的数组/列表,所需的方法如下所示:

    public static <K, E> void values(Multimap<K, E> m1, Multimap<K, E> m2) {
        m2.putAll(m1);
    }
    

    (不用说你一开始就不需要额外的方法)。

    接口允许简单的插入模式

    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 =)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-03-16
      • 1970-01-01
      • 1970-01-01
      • 2021-04-26
      • 2011-08-18
      • 1970-01-01
      • 2019-08-26
      • 2015-06-28
      相关资源
      最近更新 更多