对 HashMap<Integer, String>调用 get(byte 变量) 为何取不到值?

2020-03-30 13:46:11 +08:00
 amiwrong123
public class test {
    public static void main(String[] args) throws IOException {
        HashMap<Integer, String> map= new HashMap<>();
        map.put(1,"one");
        String aa = map.get(1);
        byte b =1;
        String bb = map.get(b);
    }
}

如上代码,为何 bb 变量是 null 呢,感觉不是 byte 自动转型为 int,再自动装箱为 Integer 吗

4686 次点击
所在节点    Java
24 条回复
1194129822
2020-03-30 23:45:42 +08:00
楼主对 hashmap,基本类型及其包装类,自动装箱及隐私类型转换,类型提升不是很熟悉啊。首先 Java 泛型并不支持基本类型,java 默认的整型是 int,浮点数是 double,所以没有特别标注 1,2 这些字面量表示就是 int,当在泛型方法中使用时,会自动装箱为 Integer,如果强行指定(byte)1 则会包装为 Byte,hashmap 判定两个元素是否相等是 equals,而 hashcode 相同只是处在相同的 bin 中。所以当然为 null 啦,而 Integer(1)与 Byte(1)当然就不相同啦,这里还有个坑,因为 Byte,Integer 缓存了 1byte 的值,所以你 put/get(1)多少次只是 1 个包装对象,而 get(128)就会每次生成一个新对象,虽然包装类都重写了 equals,但还是会稍微影响点性能,而 java 默认的隐式类型装是针对基本类型的,换是 int 可以接受 byte,注意 Byte 不能转换为 Integer 。而类型提升也是针对基本类型的,算数位移等运算符只能是基本类型,并且默认提升到***int***,所以 byte(1)+byte(1)=int(2). 所以你只要 get(byte(1)+0)就相当于 get(1)了,推荐看一下 java 规范
xiaowangge
2020-03-31 00:42:50 +08:00
1 、debug 大法好:
在 IDEA 中,在 `String bb = map.get(b);` 这一行打断点,然后 debug 运行,force step into

public static Byte valueOf(byte b) {
final int offset = 128;
return ByteCache.cache[(int)b + offset];
}



2 、javap 大法好:

35: invokestatic #9 // Method java/lang/Byte.valueOf:(B)Ljava/lang/Byte;
Aresxue
2020-03-31 15:21:18 +08:00
很有趣的问题, 看了下源码 byte b 在处理时被装箱成了 Byte,有趣的是 new Byte(1)和 new Integer(1)的 hashCode 是一样的, 这很容易让人困惑, 但在 HashMap 569 行(k = first.key) == key || (key != null && key.equals(k))) 中对 key 除了 hashCode 的判断还有对类型的判断(见 Integer equals 方法 974 行)。同理你使用 map.get(new Integer(1)) 就可以取出对应的值来, 哪怕不是同一个对象也依旧可以取出你想要的值, 因为 new Integer(1) equals new Integer(1)
SoloCompany
2020-03-31 19:47:42 +08:00
关键在于 Map.get 的签名是 get(Object key) 而并不是 get(K key)

虽然 put 的签名是 put(K key, V value)

然而 get 和 put 并不对等

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://tanronggui.xyz/t/657545

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX