【问题标题】:How to make a set backed by a map?如何制作由地图支持的集合?
【发布时间】:2012-11-11 13:18:29
【问题描述】:

Collections 类中有一个方法。

Set<E> Collections.newSetFromMap(<backing map>)

后备地图地图后备的集合是什么意思?

【问题讨论】:

    标签: java collections map set


    【解决方案1】:

    我刚刚为你做了一个示例代码

    HashMap<String, Boolean> map = new HashMap<String, Boolean>();
    
    Set<String> set = Collections.newSetFromMap(map);
    
    System.out.println(set);
    
    for (int i = 0; i < 10; i++)
        map.put("" + i, i % 2 == 0);
    
    System.out.println(map);
    
    System.out.println(set);
    

    和输出

    []
    {3=false, 2=true, 1=false, 0=true, 7=false, 6=true, 5=false, 4=true, 9=false, 8=true}
    [3, 2, 1, 0, 7, 6, 5, 4, 9, 8]
    

    【讨论】:

    • 来自 Javadoc:对于已经有对应 Set 实现(例如 HashMap 或 TreeMap)的 Map 实现,无需使用此方法。
    【解决方案2】:

    简单地说,Collections.newSetFromMap 使用提供的Map&lt;E&gt; 实现来存储Set&lt;E&gt; 元素。

    【讨论】:

      【解决方案3】:

      Set 在内部使用 Map 来存储值。这里的backing map指的是set内部使用的set map。 了解更多信息。 http://www.jusfortechies.com/java/core-java/inside-set.php

      【讨论】:

        【解决方案4】:

        也许看看实现会很有启发性:

        private static class SetFromMap<E> extends AbstractSet<E>
            implements Set<E>, Serializable
        {
            private final Map<E, Boolean> m;  // The backing map
            private transient Set<E> s;       // Its keySet
        
            SetFromMap(Map<E, Boolean> map) {
                if (!map.isEmpty())
                    throw new IllegalArgumentException("Map is non-empty");
                m = map;
                s = map.keySet();
            }
        
            public void clear()               {        m.clear(); }
            public int size()                 { return m.size(); }
            public boolean isEmpty()          { return m.isEmpty(); }
            public boolean contains(Object o) { return m.containsKey(o); }
            public boolean remove(Object o)   { return m.remove(o) != null; }
            public boolean add(E e) { return m.put(e, Boolean.TRUE) == null; }
            public Iterator<E> iterator()     { return s.iterator(); }
            public Object[] toArray()         { return s.toArray(); }
            public <T> T[] toArray(T[] a)     { return s.toArray(a); }
            public String toString()          { return s.toString(); }
            public int hashCode()             { return s.hashCode(); }
            public boolean equals(Object o)   { return o == this || s.equals(o); }
            public boolean containsAll(Collection<?> c) {return s.containsAll(c);}
            public boolean removeAll(Collection<?> c)   {return s.removeAll(c);}
            public boolean retainAll(Collection<?> c)   {return s.retainAll(c);}
            // addAll is the only inherited implementation
        
            private static final long serialVersionUID = 2454657854757543876L;
        
            private void readObject(java.io.ObjectInputStream stream)
                throws IOException, ClassNotFoundException
            {
                stream.defaultReadObject();
                s = m.keySet();
            }
        }
        

        编辑 - 添加说明:

        您提供的地图用作此对象中的m 字段。

        当您将元素 e 添加到集合时,它会将条目 e -&gt; true 添加到地图中。

        public boolean add(E e) { return m.put(e, Boolean.TRUE) == null; }
        

        因此,这个类将您的 Map 变成一个行为类似于 Set 的对象,只需忽略映射到的值,而只使用键。

        【讨论】:

        • 我的主要问题是支持集和地图..它们是什么意思,一个简单的例子会很有用..
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-08-26
        • 2023-03-09
        • 2019-01-03
        • 2019-10-12
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多