Java Hashtable使用int与byte类型键的匹配异常问题咨询
为什么用Byte查询Integer键的Hashtable会返回null?
这个问题的核心其实出在Hashtable的查找逻辑以及Byte和Integer的equals()方法实现上,咱们一步步拆解:
1. Hashtable的查找是「两步走」逻辑
Hashtable(包括HashMap这类哈希集合)的get()方法不是只靠哈希码就能找到值的,它的完整流程是:
- 第一步:根据传入键的哈希码定位到对应的存储桶
- 第二步:遍历桶内元素,用
equals()方法逐一比较传入键与桶内键是否相等,只有两者都匹配才会返回对应值
你提到Byte和Integer的哈希码都是10,所以第一步确实能找到正确的桶,但第二步的equals()比较失败了,这才是返回null的关键。
2. Byte和Integer的equals()方法互不兼容
咱们直接看这两个包装类的equals()实现逻辑:
Byte的equals():只认同类型的对象,源码逻辑大概是:
意思是,只有当传入对象是public boolean equals(Object obj) { return obj instanceof Byte && value == ((Byte)obj).byteValue(); }Byte类型且值相等时,才返回true。Integer的equals():同理,只接受Integer对象:public boolean equals(Object obj) { return obj instanceof Integer && value == ((Integer)obj).intValue(); }
所以当你用Byte b = new Byte(10)调用table.get(b)时,桶里的键是Integer(10),此时做Integer(10).equals(Byte(10))判断时,因为Byte(10)不是Integer类型,直接返回false;反过来Byte(10).equals(Integer(10))也会因为类型不匹配返回false。equals判断不通过,自然拿不到对应的值。
3. 为什么其他调用方式能成功?
再看你测试的几种场景:
table.get((int)b):把Byte转成int后会自动装箱成Integer对象,此时和桶里的Integer(10)类型匹配、值相等,equals判断通过,就能找到结果。table.get(10):int字面量会自动装箱成Integer(10),同样满足匹配条件。table.get((byte)10):byte字面量自动装箱成Byte(10),回到了之前的类型不匹配问题,equals判断失败,返回null。
总结一下:哈希码相同只是让它们进入了同一个桶,但类型不同导致equals判断不通过,这才是拿不到值的根本原因。
内容的提问来源于stack exchange,提问作者Droidum
相关产品推荐
相关产品推荐

