ConcurrentHashMap 为什么不允许key和value为null

在Java中,ConcurrentHashMap是一种线程安全的哈希表实现,广泛用于并发编程场景中。与传统的HashMap不同,ConcurrentHashMap不允许null键或null值。这种设计并非随意而为,而是经过深思熟虑的决定。


1. 并发操作中的歧义问题

1.1 null键的歧义

ConcurrentHashMap中,如果允许null键,当我们调用map.get(null)时,返回null意味着什么?

阅读更多

Java 集合研究


允许存储 null 的集合

List 接口的实现类

  • **ArrayList**:允许 null
  • **LinkedList**:允许 null
阅读更多

Java集合使用经验

集合判空

《阿里巴巴 Java 开发手册》的描述如下:

判断所有集合内部的元素是否为空,使用 isEmpty() 方法,而不是 size()==0 的方式。

这是因为 isEmpty() 方法的可读性更好,并且时间复杂度为 O(1)

绝大部分我们使用的集合的 size() 方法的时间复杂度也是 O(1),不过,也有很多复杂度不是 O(1) 的,比如 java.util.concurrent 包下的 ConcurrentLinkedQueueConcurrentLinkedQueueisEmpty() 方法通过 first() 方法进行判断,其中 first() 方法返回的是队列中第一个值不为 null 的节点(节点值为null的原因是在迭代器中使用的逻辑删除)

阅读更多

Java HashMap

HashMap 简介

HashMap 主要用来存放键值对,它基于哈希表的Map接口实现,是常用的Java集合之一。

JDK1.8 之前 HashMap 由 数组+链表 组成的,数组是 HashMap 的主体,链表则是主要为了解决哈希冲突而存在的(“拉链法”解决冲突).JDK1.8 以后在解决哈希冲突时有了较大的变化,当链表长度大于阈值(默认为 8)时,将链表转化为红黑树,以减少搜索时间。

底层数据结构分析

JDK1.8之前

JDK1.8 之前 HashMap 底层是 数组和链表 结合在一起使用也就是 链表散列HashMap 通过 key 的 hashCode 经过扰动函数处理过后得到 hash 值,然后通过 (n - 1) & hash 判断当前元素存放的位置(这里的 n 指的时数组的长度),如果当前位置存在元素的话,就判断该元素与要存入的元素的 hash 值以及 key 是否相同,如果相同的话,直接覆盖,不相同就通过拉链法解决冲突。

阅读更多