Java HashMap 中的键存在检查
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3626752/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Key existence check in HashMap
提问by athena
Is checking for key existence in HashMap always necessary?
是否总是需要检查 HashMap 中的键是否存在?
I have a HashMap with say a 1000 entries and I am looking at improving the efficiency. If the HashMap is being accessed very frequently, then checking for the key existence at every access will lead to a large overhead. Instead if the key is not present and hence an exception occurs, I can catch the exception. (when I know that this will happen rarely). This will reduce accesses to the HashMap by half.
我有一个带有 1000 个条目的 HashMap,我正在考虑提高效率。如果 HashMap 被非常频繁地访问,那么在每次访问时检查 key 是否存在会导致很大的开销。相反,如果密钥不存在并因此发生异常,我可以捕获异常。(当我知道这很少发生时)。这将使对 HashMap 的访问减少一半。
This might not be a good programming practice, but it will help me reduce the number of accesses. Or am I missing something here?
这可能不是一个好的编程习惯,但它会帮助我减少访问次数。还是我在这里遗漏了什么?
[Update] I do not have null values in the HashMap.
[更新] 我在 HashMap 中没有空值。
采纳答案by Jon Skeet
Do you ever store a null value? If not, you can just do:
你曾经存储过空值吗?如果没有,你可以这样做:
Foo value = map.get(key);
if (value != null) {
...
} else {
// No such key
}
Otherwise, you couldjust check for existence if you get a null value returned:
否则,如果返回空值,则可以检查是否存在:
Foo value = map.get(key);
if (value != null) {
...
} else {
// Key might be present...
if (map.containsKey(key)) {
// Okay, there's a key but the value is null
} else {
// Definitely no such key
}
}
回答by Jon Freedman
I usually use the idiom
我通常使用成语
Object value = map.get(key);
if (value == null) {
value = createValue(key);
map.put(key, value);
}
This means you only hit the map twice if the key is missing
这意味着如果钥匙丢失,你只会点击地图两次
回答by jkff
Do you mean that you've got code like
你的意思是你有这样的代码
if(map.containsKey(key)) doSomethingWith(map.get(key))
if(map.containsKey(key)) doSomethingWith(map.get(key))
all over the place ? Then you should simply check whether map.get(key)
returned null and that's it.
By the way, HashMap doesn't throw exceptions for missing keys, it returns null instead. The only case where containsKey
is needed is when you're storing null values, to distinguish between a null value and a missing value, but this is usually considered bad practice.
到处都是 ?然后你应该简单地检查是否map.get(key)
返回 null 就是这样。顺便说一下,HashMap 不会为丢失的键抛出异常,而是返回 null。唯一containsKey
需要的情况是当您存储空值时,以区分空值和缺失值,但这通常被认为是不好的做法。
回答by Colin Hebert
You won't gain anything by checking that the key exists. This is the code of HashMap
:
通过检查密钥是否存在,您不会获得任何好处。这是代码HashMap
:
@Override
public boolean containsKey(Object key) {
Entry<K, V> m = getEntry(key);
return m != null;
}
@Override
public V get(Object key) {
Entry<K, V> m = getEntry(key);
if (m != null) {
return m.value;
}
return null;
}
Just check if the return value for get()
is different from null
.
只需检查 的返回值get()
是否不同于null
。
This is the HashMap source code.
这是 HashMap 源代码。
Resources :
资源 :
HashMap source codeBad one- HashMap source codeGood one
HashMap 源代码 差一- HashMap 源代码不错的一个
回答by Boris
- If key class is your's make sure the hashCode() and equals() methods implemented.
- Basically the access to HashMap should be O(1) but with wrong hashCode method implementation it's become O(n), because value with same hash key will stored as Linked list.
- 如果关键类是您的,请确保实现了 hashCode() 和 equals() 方法。
- 基本上对 HashMap 的访问应该是 O(1) 但如果使用错误的 hashCode 方法实现它变成了 O(n),因为具有相同哈希键的值将存储为链表。
回答by Dead Programmer
Better way is to use containsKey
method of HashMap
. Tomorrow somebody will add null to the Map. You should differentiate between key presence and key has null value.
更好的办法是使用containsKey
的方法HashMap
。明天有人会在 Map 中添加 null。您应该区分密钥存在和密钥具有空值。
回答by Mikko Wilkman
Just use containsKey()
for clarity. It's fast and keeps the code clean and readable. The whole point of HashMap
s is that the key lookup is fast, just make sure the hashCode()
and equals()
are properly implemented.
只是containsKey()
为了清楚起见。它很快并且保持代码干净和可读。HashMap
s的全部意义在于密钥查找速度很快,只需确保hashCode()
和equals()
正确实现即可。
回答by Erlan
if(map.get(key) != null || (map.get(key) == null && map.containsKey(key)))
回答by davidxxx
The Jon Skeet answeraddresses well the two scenarios (map with null
value and not null
value) in an efficient way.
Jon Skeet 的回答以一种有效的方式很好地解决了两种情况(null
有价值的地图和无价值的地图null
)。
About the number entries and the efficiency concern, I would like add something.
关于数量条目和效率问题,我想补充一些。
I have a HashMap with say a 1.000 entries and I am looking at improving the efficiency. If the HashMap is being accessed very frequently, then checking for the key existence at every access will lead to a large overhead.
我有一个带有 1.000 个条目的 HashMap,我正在考虑提高效率。如果 HashMap 被非常频繁地访问,那么在每次访问时检查 key 是否存在会导致很大的开销。
A map with 1.000 entries is not a huge map.
As well as a map with 5.000 or 10.000 entries.Map
are designed to make fast retrieval with such dimensions.
包含 1.000 个条目的地图并不是一张巨大的地图。
以及包含 5.000 或 10.000 个条目的地图。Map
旨在使用此类维度进行快速检索。
Now, it assumes that hashCode()
of the map keys provides a good distribution.
现在,它假设hashCode()
映射键提供了良好的分布。
If you may use an Integer
as key type, do it.
Its hashCode()
method is very efficient since the collisions are not possible for unique int
values :
如果您可以使用Integer
as 键类型,请执行此操作。
它的hashCode()
方法非常有效,因为对于唯一int
值不可能发生冲突:
public final class Integer extends Number implements Comparable<Integer> {
...
@Override
public int hashCode() {
return Integer.hashCode(value);
}
public static int hashCode(int value) {
return value;
}
...
}
If for the key, you have to use another built-in type as String
for example that is often used in Map
, you may have some collisions but from 1 thousand to some thousands of objects in the Map
, you should have very few of it as the String.hashCode()
method provides a good distribution.
如果对于键,您必须使用另一种内置类型String
,例如 中经常使用的Map
,您可能会发生一些碰撞,但是 中的 1000 到数千个对象Map
,您应该很少有它作为String.hashCode()
方法提供了良好的分布。
If you use a custom type, override hashCode()
and equals()
correctly and ensure overall that hashCode()
provides a fair distribution.
You may refer to the item 9 of Java Effective
refers it.
Here's a postthat details the way.
如果您使用的自定义类型,覆盖hashCode()
和equals()
准确,确保整体是hashCode()
提供一个公平的分配。
你可以参考参考它的第9项Java Effective
。
这是一篇详细介绍方法的帖子。
回答by nazmul idris
You can also use the computeIfAbsent()
method in the HashMap
class.
您也可以computeIfAbsent()
在HashMap
类中使用该方法。
In the following example, map
stores a list of transactions (integers) that are applied to the key (the name of the bank account). To add 2 transactions of 100
and 200
to checking_account
you can write:
在以下示例中,map
存储应用于键(银行帐户名称)的交易(整数)列表。要添加的2个交易100
,并200
以checking_account
可以这样写:
HashMap<String, ArrayList<Integer>> map = new HashMap<>();
map.computeIfAbsent("checking_account", key -> new ArrayList<>())
.add(100)
.add(200);
This way you don't have to check to see if the key checking_account
exists or not.
这样您就不必检查密钥是否checking_account
存在。
- If it does not exist, one will be created and returned by the lambda expression.
- If it exists, then the value for the key will be returned by
computeIfAbsent()
.
- 如果它不存在,则 lambda 表达式将创建并返回一个。
- 如果存在,则键的值将由 返回
computeIfAbsent()
。
Really elegant!
真的很优雅!