最常用高效方式是用HashMap统计元素频次:遍历列表,用getOrDefault更新计数;Stream API可一行实现groupingBy+counting;自定义对象需重写equals/hashCode,保序用LinkedHashMap。

在 Java 中统计 ArrayList 中每个元素的出现次数,最常用、清晰且高效的方式是使用 HashMap(或 Map 接口的其他实现,如 LinkedHashMap 或 Java 8+ 的 ConcurrentHashMap)来记录“元素 → 出现次数”的映射关系。
用 HashMap 遍历计数(推荐,通用性强)
这是最基础也最灵活的方法:遍历列表,对每个元素,先查 Map 中是否已有该键;有则值 +1,无则放入键并设值为 1。
示例代码:
import java.util.*;
List<String> list = Arrays.asList("apple", "banana", "apple", "cherry", "banana", "apple");
Map<String, Integer> countMap = new HashMap<>();
for (String item : list) {
countMap.put(item, countMap.getOrDefault(item, 0) + 1);
}
// 输出结果
countMap.forEach((k, v) -> System.out.println(k + ": " + v));
// apple: 3
// banana: 2
// cherry: 1
用 Java 8 Stream API(简洁,函数式风格)
适合喜欢函数式写法、且数据量不极端大的场景。借助 Collectors.groupingBy 和 Collectors.counting() 可一行完成统计。
立即学习“Java免费学习笔记(深入)”;
注意:返回的是 Map<T, Long>,计数值是 Long 类型。
Map<String, Long> countMap = list.stream()
.collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));
若需 Integer 值,可改用自定义收集器,或后续转换(如 .map(Long::intValue)),但通常 Long 足够安全。
处理自定义对象时要注意 equals 和 hashCode
如果 ArrayList 存的是自定义类(如 Person),必须正确重写 equals() 和 hashCode() 方法,否则 HashMap 或 groupingBy 会把逻辑相等的对象当成不同键,导致计数错误。
例如:
- 没重写:两个属性相同的
Person对象可能被算作两个不同元素; - 正确重写后:
HashMap才能按内容而非引用判断是否重复。
需要保持插入顺序?选 LinkedHashMap
默认 HashMap 不保证遍历顺序。如果希望输出按首次出现顺序(或插入顺序)排列,可将 HashMap 换成 LinkedHashMap:
Map<String, Integer> countMap = new LinkedHashMap<>(); // 后续逻辑不变,put 顺序即首次出现顺序
Stream 方式中,groupingBy 默认不保序;如需保序,可显式传入 LinkedHashMap::new 作为 map 工厂:
Map<String, Long> countMap = list.stream()
.collect(Collectors.groupingBy(
Function.identity(),
LinkedHashMap::new,
Collectors.counting()
));
不复杂但容易忽略细节。核心就三点:选对容器(Map)、遍历或流式聚合、自定义类型记得重写 equals/hashCode。


















