【问题标题】:Java, quickest way to determine if any values in hashmap match a value?Java,确定hashmap中的任何值是否匹配值的最快方法?
【发布时间】:2011-08-08 22:18:56
【问题描述】:

请原谅我的 Java 新手,因为我没有足够的经验知道最有效的方法。我有一个如下所示的哈希图,但它应该有 40,000 个条目:

Map <String, String> someHashmap = new HashMap <String, String> ();
someHashmap.put("filepath1", null);
someHashmap.put("filepath2", "tag1");
someHashmap.put("filepath3", "tag2");

我想确定有多少值匹配null,以便确定是否有任何值为空。当然我可以做一个常规循环来检查,但我想知道是否有更有效的方法,谢谢

【问题讨论】:

    标签: java dataset hashmap


    【解决方案1】:

    如果您真的需要速度,您将neeed将哈希集中的使用值存储在HashMap之外。例如(未测试!)。

    public class MapWithVals<K, V> extends HashMap<K, V> {
    
        protected final Set<V> vals = new HashSet<V>();
    
        public MapWithVals() {
            super();
        }
    
        public MapWithVals(Map<? extends K, ? extends V> m) {
            super(m);
            vals.addAll(m.values());
        }
    
        @Override
        public void clear() {
            super.clear();
            vals.clear();
        }
    
        @Override
        public V put(K arg0, V arg1) {
            vals.add(arg1);
            return super.put(arg0, arg1);
        }
    
    
        @Override
        public V remove(Object arg0) {
            V val = get(arg0);
            super.remove(arg0);
            if( ! super.containsValue(val) ) vals.remove(val);
            return val;
        }
    
        @Override
        public boolean containsValue(Object value) {
            return vals.contains(value);
        }
    
        @Override
        public void putAll(Map<? extends K, ? extends V> arg0) {
            super.putAll(arg0);
            vals.addAll(arg0.values());
        }
    
        @Override
        public Object clone() {
            throw new RuntimeException("not implemented");
        }
    
    }
    

    【讨论】:

    • 如果在原始哈希图中存在重复值,则不起作用,如果您希望从原始哈希映射中删除元素。 span>
    • ESP。由于OP对NULLS感兴趣! span>
    • 您的新代码包含错误;您将拨打您的派生类版本containsValue()而不是super.containsValue()。即使在添加该更改后,您也成功地制作了containsValue() O(1),但在制作remove() O(n)的成本上。 span>
    • @ jprete谢谢,修复了(已经在之前修复了,但它滑倒)。是的,如果频繁remove()这会得到空间 - 在那种情况下,应该在你建议的情况下实现一个计数器。 span>
    【解决方案2】:

    由于您只对null 感兴趣,因此每次将put 放入HashMap 时,您都可以检查该值是否为null 并将key 存储在HashSet 中。

    然后你必须注意同步地图中的所有 CRUD HashSet

    【讨论】:

      【解决方案3】:

      这是一个替代解决方案,设计用于速度。

      致电您的原始HashMap a。有一个第二个HashMap&lt;String, Integer&gt; aCountaCount哈希映射将存储在原来的哈希地图中的每个值中有多少计数。

      每次插入钥匙k和value v,@,请检查是否aCount.containsKey(v)。如果它,那么递增值:aCount.put(v, aCount.get(v) + 1)。否则,添加新条目:aCount.put(v, 1)

      每次删除钥匙kv,请从第一个HashMap,检查使用aCount.get(v)。如果计数大于1,则使用@ 987654334释放计数。否则(即计数恰好是一个)使用aCount.remove(v)

      然后,您只需要调用aCount.contains(v)以了解给定值是否在您的HashMap a

      为什么这一切?因为,这种方式,而不是拥有o(n)查询时间来查明您的hashmap中的值是否存在,则获得O(1)时间。如果这对您有价值,那么上述解决方案将工作。如果这对你无关紧要,那么你可以轻松地使用Mike Lewis的答案。

      【讨论】:

        【解决方案4】:

        您可以使用containsValue方法,这些方法:

        如果此地图映射一个或 指定值的更多键。

        somHashmap.containsValue(null);
        
        但是,请记住,如果您有一个大型数据集(并且似乎您正在执行),则应创建一个单独的数据结构,以跟踪允许O(1)查找时间而不是O( n)时间,如其他答案所示。

        【讨论】:

        • 但通常不会快速。从文档中可能需要在地图界面的大多数实现的地图大小中需要时间线性。“与所有地图 span>迭代而不同
        • 我认为可以在代码中处理这些东西,只是你要建立一些类似于数据库所拥有的数据结构。当您有足够的不同查询时,DB绝对是前进方式。 span>
        • @ leonboy:有两个含义快速 i> - 这是快速编程的。 span>
        猜你喜欢
        • 1970-01-01
        • 2013-08-23
        • 2016-03-18
        • 2012-02-10
        • 2020-08-09
        • 1970-01-01
        • 1970-01-01
        • 2021-07-31
        • 1970-01-01
        相关资源
        最近更新 更多