为什么java.util.Map.containsKey会对不';不支持空键?
java文档这样说: 抛出: ClassCastException-如果键的类型不适合此映射(可选) NullPointerException-如果指定的键为null且此映射不允许使用null键(可选) 我确信这个决定有很好的理由,但我不知道确切的原因是什么。containsKey是否应该始终返回false,即使映射不允许将null值作为键?如果映射不允许键,Null显然不是映射中的键,因此我认为它应该返回false 我想到的一个特别的例子是树形图。出于性能原因,我将一个映射实例从HashMap更改为TreeMap,这导致了一个微妙的错误,因为containsKey for HashMap不会引发空指针异常。我觉得这种类型的更改没有很好的理由导致这样一个微妙的错误为什么java.util.Map.containsKey会对不';不支持空键?,java,hashmap,treemap,Java,Hashmap,Treemap,java文档这样说: 抛出: ClassCastException-如果键的类型不适合此映射(可选) NullPointerException-如果指定的键为null且此映射不允许使用null键(可选) 我确信这个决定有很好的理由,但我不知道确切的原因是什么。containsKey是否应该始终返回false,即使映射不允许将null值作为键?如果映射不允许键,Null显然不是映射中的键,因此我认为它应该返回false 我想到的一个特别的例子是树形图。出于性能原因,我将一个映射实例从HashMap
编辑我知道NullPointerException的(可选)性质。在我看来,它的可选性并不能解释为什么它是被允许的 为了解释我为什么对此感到困惑,containsKey本质上是通过相等来比较键。在某种程度上,我来自一个功能背景,其中(比如说,Haskell)containsKey的等价物将有一个等式约束,并且对所有可以通过等式进行比较的值都有效 警察说 对于任何非空引用值x,x.equals(null)应返回false
因此,如果映射不支持空键,我认为containsKey必须返回false,因为实现“应该”相当于使用k.equals(输入)迭代键。我认为这是一个设计决策 有两种可能的情况: 1。在支持空键的映射上使用containsKey。作为此函数的用户,您希望得到true或false。绝对没有理由返回nullPointerException,因为我们将“null”视为任何其他键,因此,如果“someKey”不存在,您可能会期望它返回false,对于null也是如此
2。在不支持空键的映射上使用containsKey。返回false将是一个奇怪的决定,因为它不是一个可能的键。此外,用户可能有对某个对象的引用,他试图将该对象用作密钥。用户希望获取NullPointerException,以便他能够意识到这种情况,尝试获取/设置null对象作为键。您的参数均匀地应用于
ClassCastException
:即使映射不允许该类型的值作为键,containsKey不应该总是返回false吗
答:API(有文档记录的行为)不强制实现检查给定密钥的有效性,而是允许对无效的键值引发异常
请注意,这两个异常都列为“(可选)”,这意味着是否这样做取决于实现。实现可以选择简单地返回false
,也可以选择抛出其中一个异常
实现可能会选择不为此添加特殊逻辑,所以如果算法“本机”抛出异常,那么就这样吧。API被记录为允许此默认行为
例如,TreeMap
将本机抛出ClassCastException
,因为在尝试调用compare()
/compareTo()
时会发生这种情况HashMap
不关心对象类型,因此永远不会抛出ClassCastException
如果给定的键为null,则不支持null键的映射的
containsKey()
逻辑可能会或可能不会执行引发NullPointerException
,这是一个有效的结果,因此逻辑不必浪费额外的代码来处理它。首先,containsKey(对象键)
在Map
接口中声明,因此,它取决于实现
如果问题是为什么实现不在内部执行所有这些(null,cast)检查,为什么它们抛出异常,我认为这是因为设计,并且有一个很好的理由,可以清楚地告诉输出出了什么问题
请注意:
null
,这也是处理此场景的原因