Collections.frequency采用线性遍历,时间复杂度O(n),通过equals()逐个比较计数,支持null,结果依赖equals实现,频繁查询时建议改用Map或Stream预统计。

Collections.frequency 方法内部采用的是最直接的线性遍历方式,不依赖哈希或排序,适用于任意 Collection(包括 List、Set、Queue 等)。
遍历逻辑:逐个比较,计数累加
该方法接收一个集合和一个目标对象,内部通过增强 for 循环(即迭代器遍历)依次访问每个元素,并调用 equals() 方法判断是否与目标对象相等。匹配一次,计数器加 1。
- 遍历顺序与集合本身的迭代顺序一致(如 ArrayList 按索引顺序,LinkedHashSet 按插入顺序)
- 不提前终止——即使目标元素出现频率很高,也会完整遍历整个集合
- 时间复杂度为 O(n),空间复杂度为 O(1)
- 对 null 值有专门处理:当目标为 null 时,使用
e == null判断,避免调用null.equals()
关键细节:equals() 的行为决定统计结果
统计是否准确,完全取决于集合中元素的 equals() 实现。例如:
- 若元素是自定义类,但未重写
equals(),则默认使用Object.equals()(即引用相等),可能导致本应匹配的逻辑相等对象被漏计 - 若集合中存在多个语义相同但
equals()返回 false 的对象(比如两个 new String("a") 在未重写或未启用字符串常量池时),它们不会被同时计入 - 推荐确保目标对象与集合中元素类型兼容,且 equals 语义合理
不适用场景与替代建议
当需要频繁查询多个不同元素的频次时,Collections.frequency 效率较低(每次调用都全量扫描)。此时更适合预构建频次映射:
立即学习“Java免费学习笔记(深入)”;
- 用
Map<t integer></t>一次性遍历集合并统计所有元素频次(O(n) 总成本) - Java 8+ 可用
stream().collect(Collectors.groupingBy(..., Collectors.counting())) - 第三方库如 Guava 的
Multiset或 Apache Commons Collections 的Bag提供更自然的频次操作接口
简单示例说明执行过程
对 List<string> list = Arrays.asList("a", "b", "a", "c", "a")</string> 调用 Collections.frequency(list, "a"):
- 第 1 次:list.get(0).equals("a") → true,count = 1
- 第 2 次:list.get(1).equals("a") → false,count = 1
- 第 3 次:list.get(2).equals("a") → true,count = 2
- 第 4 次:list.get(3).equals("a") → false,count = 2
- 第 5 次:list.get(4).equals("a") → true,count = 3
- 返回 3


















