文章目录
- 1. key的匹配
- 2. transient 修饰数组
- 3. putAll
- 4. entrySet、keySet 等集合
ps:HashMap 相关的源码分析,网上有写很多了,这里就不献丑了。本文主要写我个人觉得注意的一些点。
1. key的匹配
map匹配key,是 == 或者 equals相等。这里就有个要注意的地方,如果key是用的一个对象,两个对象的equals方法相等,则在map的key就是相等的。
2. transient 修饰数组
第一个原因,数组多数情况下是不满的,序列化未使用的部分会浪费空间,这个大家都知道。
第二个原因谈到的比较少:同一个键值对在不同 JVM 下,所处的桶位置可能是不同的,在不同的 JVM 下反序列化 table 可能会发生错误。
HashMap 的get/put/remove等方法第一步就是根据 hash 找到键所在的桶位置,但如果键没有覆写 hashCode 方法,计算 hash 时最终调用 Object 中的 hashCode 方法。Object 中的 hashCode 方法是 native 型的,不同的 JVM 下,可能会有不同的实现,产生的 hash 可能也是不一样的。也就是说同一个键在不同平台下可能会产生不同的 hash,此时再对在同一个 table 继续操作,就会出现问题。
3. putAll
putAll 本质上还是复用put方法一个个添加元素的,并不会在一开始就申请好足够的容量,所以是有可能出现多次resize的。
4. entrySet、keySet 等集合
与 ArrayList的subList类似,本质也是映射到HashMap的,并没有单独申请内存并存储数据,所以对他们进行修改时,也会影响到原来的HashMap。