请原谅我对Java的新手,因为我没有足够的经验知道最有效的方法。我有一个类似下面的哈希映射,但它有40,000个条目:
Map <String, String> someHashmap = new HashMap <String, String> ();
someHashmap.put("filepath1", null);
someHashmap.put("filepath2", "tag1");
someHashmap.put("filepath3", "tag2");
我想确定有多少值匹配null
,以便我可以确定是否有空值。当然我可以定期循环来检查,但我想知道是否有更有效的方式,谢谢
答案 0 :(得分:12)
您可以使用containsValue
方法,其中声明:
如果此地图映射一个或,则返回true 更多指定值的键。
somHashmap.containsValue(null);
但是请记住,如果你有一个大型数据集(似乎你有),你应该创建一个单独的数据结构来跟踪允许O(1)查找时间的值,而不是O( n)时间,如其他答案所示。
答案 1 :(得分:4)
这是一种替代解决方案,专为速度而设计。
调用原始HashMap a
。请等一下HashMap<String, Integer> aCount
。 aCount
哈希映射将存储原始哈希映射中每个值的数量。
每次向第一个k
插入密钥v
和值HashMap
时,请检查aCount.containsKey(v)
是否为aCount.put(v, aCount.get(v) + 1)
。如果是,则递增值aCount.put(v, 1)
。否则,请添加新条目:k
。
每次从第一个v
移除密钥HashMap
和值aCount.get(v)
时,请使用aCount.put(v, aCount.get(v) - 1)
检查计数。如果计数大于1,则使用aCount.remove(v)
递减计数。否则(即计数恰好是一个)使用aCount.contains(v)
。
然后,您只需要调用a
来确定给定值是否在您的HashMap {{1}}中。
为什么这一切?因为这样,您可以获得O(1)时间,而不是通过O(n)查询时间来查找HashMap中是否存在值。如果这对您有价值,那么上述解决方案将起作用。如果这对您无关紧要,那么您可以轻松使用Mike Lewis的答案。
答案 2 :(得分:0)
如果你真的需要速度,除了HashMap之外,你需要将使用过的值存储在HashSet中。例如(未经测试!)。
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");
}
}
答案 3 :(得分:0)
由于您只对null
感兴趣,因此每次put
进入HashMap
,您都可以检查该值是否为null
并存储key
在HashSet
。
然后你必须照顾来自Map&lt; - &gt;的所有CRUD的同步。 HashSet的