优先用 isempty() 判断集合是否为空,因其语义明确、安全高效;list == null 仅判引用存在性,非内容空;需先判非空再调 isempty() 或初始化即避免 null。

Java里判断集合是否为空,优先用 isEmpty(),别用 size() == 0,更不要用 == null 直接判空——后者根本不是在判断“是否为空”,而是在判断“是否存在”。
为什么不能用 list == null 判断集合是否为空
这是最常见的误用:list == null 检查的是引用是否为 null,和集合内容无关。一个刚 new ArrayList() 出来的对象不为 null,但确实是空的;而一个为 null 的引用,调用 isEmpty() 会直接抛 NullPointerException。
正确做法是先判空再判空内容:
- 如果业务允许
null集合存在,必须先if (list != null && list.isEmpty()) - 更推荐的做法是:初始化时就避免
null,比如用Collections.emptyList()或构造器保证非空 - Lombok 的
@NonNull或 Spring 的@NotNull可在编译/运行期提前暴露问题
isEmpty() 和 size() == 0 的实际差异
对 ArrayList、LinkedList 这类 JDK 内置集合,两者性能几乎没差别,因为 size 是字段直接返回,isEmpty() 也只是 return size == 0。但问题出在抽象层和可读性上:
立即学习“Java免费学习笔记(深入)”;
-
isEmpty()是Collection接口定义的方法,语义明确,意图清晰 -
size() == 0是“计算后比较”,多一层间接,且某些自定义集合(如懒加载视图)可能重写size()导致意外开销 - 静态分析工具(如 SonarQube)会把
size() == 0标为“可读性警告”
Stream 和 Optional 场景下的空集合处理
用 stream() 处理集合前,如果集合可能是 null,别直接 list.stream().map(...)——这会 NPE。常见安全写法:
Optional.ofNullable(list).orElse(Collections.emptyList()).stream()...- 或封装成工具方法:
safeStream(list),内部统一处理null转空流 - 注意:
Stream.empty()不等于“空集合的 stream”,它本身就是一个确定的空流,和源集合是否null无关
Map 的“空”要单独对待
Map 不是 Collection 子接口,但同样有 isEmpty() 方法,用法一致。不过要注意:
-
map.isEmpty()判断键值对数量是否为 0,和keySet()、values()是否为空等价 - 别误用
map.containsKey(null)或map.get(key) == null来推断 Map 是否为空——null值合法存在,且get()返回null可能只是 key 不存在 - ConcurrentHashMap 等并发集合的
isEmpty()是弱一致性判断,不保证实时精确,但对“是否为空”的业务判断通常已足够
真正容易被忽略的点是:空集合和 null 集合在 API 设计层面代表不同语义——前者是“有容器,没元素”,后者是“连容器都没有”。混用会导致边界逻辑错乱,尤其在 JSON 反序列化(Jackson 默认把缺失字段设为 null,而非空集合)或 MyBatis 查询结果中特别明显。










