对 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 吗

4623 次点击
所在节点    Java
24 条回复
IMCA1024
2020-03-30 13:52:14 +08:00
.....Integer 做 key 啊。
为什么推荐用 String 做 key 呢?

原理我不太会说,但我觉得问题在 你这个 byte b=1 的 hash 值 并不能拿到 key 为 Integer=1 的。。
希望楼下的能给我说明一下 哈哈哈
mm163
2020-03-30 13:54:30 +08:00
HashMap<Integer, String> map= new HashMap<Integer, String>();
EPr2hh6LADQWqRVH
2020-03-30 13:57:30 +08:00
要射自己脚的话直接 c++就完了嘛
earther01
2020-03-30 14:01:11 +08:00
看了下 get 前强转一下就行了,不转的话应该是认为传进去的是 object 的地址,会先寻址找到地址对应的 object
airfling
2020-03-30 14:03:21 +08:00
我刚刚测试了下你没加强转的话是取 byte 的 hash 值取值的,加了强转的话就是一样的值了
下面是 map 中的 get
~~~
public V get(Object key) {
Node<K,V> e;
return (e = getNode(hash(key), key)) == null ? null : e.value;
}
~~~
map.get((int)b) 这样获取的值就是一样的
h3nng
2020-03-30 14:15:26 +08:00
补充下楼上说的,hash 值其实是一样的,都是 1,但是 == 或 equals() 为 false
amiwrong123
2020-03-30 14:29:45 +08:00
@airfling
好吧,大概懂了。我主要之前以为函数签名是泛型类型呢 public V get(K key) {
p2pCoder
2020-03-30 14:33:29 +08:00
只会触发装箱,没有触发转型
lux182
2020-03-30 14:59:32 +08:00
个人猜测:byte 封装为 Byte 。Byte _b = 1 与 Integer _a = 1 的 hash 、equals 应该有不同
ChenFanlin
2020-03-30 15:23:28 +08:00
yeqizhang
2020-03-30 16:29:12 +08:00
@mm163 不是应该这么写?:HashMap map= new HashMap<Integer, String>();
guyeu
2020-03-30 16:31:16 +08:00
因为 HashMap.get(Object)接受任意类型的参数,当传入基本数据类型时,会触发自动装箱。

如果你声明一个这样的方法,用来替换 HashMap.get ,就会先触发类型转换,然后触发自动装箱;

```java
static <T> T get(HashMap<?, T> map, int key) {
return map.get(key);
}
```

java 貌似不支持同一个位置既自动类型转换又自动装箱。。
elevation
2020-03-30 16:35:15 +08:00
如果想彻底了解,需要学习 HashMap 源码中 put 运行机制;还有你需要写明白,自己的开发环境
yeqizhang
2020-03-30 16:36:30 +08:00
@mm163 我搞错了,楼主的是没问题的。菱形泛型
amiwrong123
2020-03-30 16:55:34 +08:00
@guyeu
java 不支持同一个位置既自动类型转换又自动装箱么,回头我试下

对,自己再写个方法可以哈。话说,你那个泛型方法 应该这样吧:

```java
static <K,V> V get(HashMap<K, V> map, K key) {
return map.get(key);
}
```
yjxjn
2020-03-30 18:17:59 +08:00
@mm163 楼主这个没写错呀,后面的菱形里面不声明也可以、
cco
2020-03-30 18:55:36 +08:00
@yeqizhang HashMap<String, Object> map= new HashMap<>();
guyeu
2020-03-30 22:17:59 +08:00
@amiwrong123 #15 你这样写没办法出发自动类型转换(你这个只不过是把 HashMap 自带的 get 方法换了个写法)
dreamist
2020-03-30 23:17:36 +08:00
这个代码,在 Kotlin 里面是会编译报错的,所以,Kotlin 欢迎你~~ hhh
dreamist
2020-03-30 23:20:40 +08:00
这个问题,究其原因,还是 HashMap 的锅,HashMap 的 get 方法参数是没有泛型约束的:
public V get(Object key) {
}

所以在 get 的时候,传入的类型,是允许和 HashMap 定义时的 key 类型是不一致的,这就导致了这样的问题无法在编译期间暴露出来。

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

https://www.v2ex.com/t/657545

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

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

© 2021 V2EX