isEmpty() 性能优势在于接口契约保障的 O(1) 确定性,而 size() == 0 在 ConcurrentLinkedQueue、Hibernate 懒加载集合等场景存在 O(n) 或 IO 开销,且语义模糊、工具告警、易受实现变更影响。

Java 中 Collection.isEmpty() 相比 size() == 0 的性能优势,核心不在“大多数常用集合里更快”,而在于确定性、契约保障与规避意外开销。
isEmpty() 是专为判空设计的 O(1) 契约方法
Collection 接口明确要求所有实现类的 isEmpty() 方法时间复杂度必须为 O(1)。这是接口契约,不是实现细节——JDK 所有标准集合(ArrayList、HashSet、LinkedList、HashMap 等)都通过直接读取内部 size 字段或头/尾节点状态完成判断,不遍历、不计算。
-
isEmpty()返回true,只依赖一个字段比较(如size == 0),无副作用 -
size()虽在多数场景也是 O(1),但它的语义是“返回当前元素个数”,并非专为判空优化
size() 在某些集合中真实存在 O(n) 开销
不是理论风险,而是已知实现:
分析 Java Spring Boot 后端 Controller 代码,自动生成 Markdown 格式的接口文档。当用户说“生成 Java 接口文档”、“生成 API 文档”、“从 Spring 代码生成文档”时触发。
-
ConcurrentLinkedQueue.size():需遍历整个链表计数,最坏 O(n),高并发下还可能因结构变化导致多次重试 - Hibernate 的懒加载代理集合(如
PersistentSet、PersistentList):调用size()会触发 SQL 查询加载全部数据,造成 N+1 或全量拉取 - 某些自定义或第三方集合(如基于流式数据源的包装类):
size()可能隐含 IO 或计算逻辑
语义清晰 + 工具友好 + 防御性强
代码意图一目了然,且被静态分析工具广泛支持:
立即学习“Java免费学习笔记(深入)”;
-
list.isEmpty()直观表达“是否没元素”,list.size() == 0是“算出来刚好是 0”,后者容易让人多想一层 - SonarQube、SpotBugs 等工具默认告警
size() == 0用法,推荐替换为isEmpty() - 即使未来集合实现变更(如升级到新版本 Hibernate 或引入新集合库),
isEmpty()仍受契约保护;size() == 0则可能突然变慢
注意前提:必须先处理 null
isEmpty() 本身不处理 null —— 对 null 调用会抛 NullPointerException:
- 正确写法:
collection != null && collection.isEmpty() - 更稳妥方式:
Objects.requireNonNullElse(collection, Collections.emptyList()).isEmpty() - 理想设计:API 尽量返回空集合而非 null(空对象模式),从源头消除判空负担


















