>>号外:关注“Java精选”公众号,回复“2021面试题”,领取免费资料! “ Java精选面试题”小程序,3000+ 道面试题在线刷,最新、 最全 Java 面试题!
首先明确一点HashMap是支持空键值对的,也就是null键和null值,而ConcurrentHashMap是不支持空键值对的。
查看一下JDK1.8源码,HashMap类部分源码,代码如下:
public V get(Object key) {
Node e;
return (e = getNode(hash(key), key)) == null ? null : e.value;static final int hash(Object key) {
int h;
return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
HashMap在调用put()方法存储数据时会调用hash()方法来计算key的hashcode值,可以从hash()方法上得出当key==null时返回值是0,这意思就是key值是null时,hash()方法返回值是0,不会再调用key.hashcode()方法。
ConcurrentHashMap类部分源码,代码如下:
public V put(K key, V value) {
return putVal(key, value, false);/** Implementation for put and putIfAbsent */
final V putVal(K key, V value, boolean onlyIfAbsent) {
if (key == null || value == null) throw new NullPointerException();
int hash = spread(key.hashCode());
int binCount = 0;
for (Node[] tab = table;;) {
Node f; int n, i, fh;
if (tab == null || (n = tab.length) == 0)
tab = initTable();
else if ((f = tabAt(tab, i = (n - 1) & hash)) == null) {
if (casTabAt(tab, i, null,
new Node(hash, key, value, null)))
break; // no lock when adding to empty bin
else if ((fh = f.hash) == MOVED)
tab = helpTransfer(tab, f);
else {
V oldVal = null;
synchronized (f) {
if (tabAt(tab, i) == f) {
if (fh >= 0) {
binCount = 1;
for (Node e = f;; ++binCount) {
K ek;
if (e.hash == hash &&
((ek = e.key) == key ||
(ek != null && key.equals(ek)))) {
oldVal = e.val;
if (!onlyIfAbsent)
e.val = value;
break;
Node pred = e;
if ((e = e.next) == null) {
pred.next = new Node(hash, key,
value, null);
break;
else if (f instanceof TreeBin) {
Node p;
binCount = 2;
if ((p = ((TreeBin)f).putTreeVal(hash, key,
value)) != null) {
oldVal = p.val;
if (!onlyIfAbsent)
p.val = value;
if (binCount != 0) {
if (binCount >= TREEIFY_THRESHOLD)
treeifyBin(tab, i);
if (oldVal != null)
return oldVal;
break;
addCount(1L, binCount);
return null;
ConcurrentHashmap在调用put()方法时调用了putVal()方法,而在该方法中判断key为null或value为null时抛出空指针异常NullPointerException。
ConcurrentHashmap是支持并发的,当通过get()方法获取对应的value值时,如果指定的键为null,则为NullPointerException,这主要是因为获取到的是null值,无法分辨是key没找到null还是有key值为null。
往期精选 点击标题可跳转
面试官问:为什么 Java 线程没有 Running 状态?一下被问懵!
SpringBoot + Mybatis + Druid + PageHelper 实现多数据源并分页(附源码)
Intellij IDEA 中的各种调试代码技巧,轻松定位 Bug 问题(涵盖超全面)
MyBatis 真坑!Integer 类型赋值 0 ,当 != '' 时无法通过判断执行 SQL 语句
面试官问:Spring Boot 中实现通用 Auth 认证,有哪几种方式?
Spring 中 IService 有多个实现类,它是如何知道该注入哪个 ServiceImpl 类?
突然慌了!面试官问:线程池中多余的线程是如何回收的?
MySQL 数据库中百万级数据量,大神是如何分页查询?
数据库中 SQL 语句使用索引,还是很慢?可能是这几点原因
Spring Boot 框架中实现跨域访问的五种解决方案,你懂了吗?
面试官问:导致 Spring 事务失效的场景有哪些,如何解决失效问题?
点个赞,就知道你“在看”!
热门跟贴