Java 中 Lambda 表达式如何实现集合元素的去重统计

作者:袖梨 2026-07-28
Java中集合去重统计需据目标选择方法:整体去重用distinct().count();按字段去重用distinctByKey()保留首条;分组统计频次用groupingBy()+counting();去重后条件统计需先去重再filter。

Java 中用 Lambda 表达式做集合去重统计,核心是结合 Stream API 的 distinct()collect()Collectors.groupingBy() 等操作,按需选择“整体去重”或“按字段去重”,再配合计数逻辑完成统计。关键不在于写得有多炫,而在于明确目标:是只去重?还是去重后统计每类数量?或是统计去重后的总数?

基础整体去重 + 统计数量

适用于元素类型已正确重写 equals()hashCode()(如 StringInteger 或自定义对象)的场景。

  • 调用 stream().distinct().count() 直接获取去重后元素个数
  • 若还需保留去重结果,用 stream().distinct().collect(Collectors.toList()) 得到新列表,再调用 size()
  • 示例:List<String> names = Arrays.asList("a", "b", "a", "c"); long uniqueCount = names.stream().distinct().count(); // 结果为 3

按指定字段去重并保留首条记录

常见于对象集合(如 List<Person>),需根据 nameid 去重,且只留第一次出现的实例。

  • 使用自定义的 distinctByKey 工具方法(基于 ConcurrentHashMap 记录已见键)
  • 代码结构固定:list.stream().filter(distinctByKey(Person::getName)).collect(Collectors.toList())
  • 去重后若要统计人数,直接对结果列表调用 size();如需同时知道每个 name 出现几次,应改用分组统计而非此方式

按字段分组统计重复频次

这不是“去重”,而是“去重统计”的另一层含义——明确各唯一值出现多少次,比如统计每个用户名出现次数。

立即学习“Java免费学习笔记(深入)”;

  • Collectors.groupingBy(keyMapper, Collectors.counting())
  • 返回 Map<K, Long>,key 是去重后的字段值,value 是该字段的出现次数
  • 示例:Map<String, Long> nameCount = persons.stream().collect(Collectors.groupingBy(Person::getName, Collectors.counting()));
  • 若只要统计结果中 key 的数量(即去重后的 name 总类数),可用 nameCount.size()

去重后按条件再统计汇总

比如:去重得到唯一用户后,再统计其中年龄大于 30 的人数。

  • 链式操作即可:list.stream().filter(distinctByKey(User::getId)).filter(u -> u.getAge() > 30).count()
  • 也可分步:先生成去重列表,再在其上用 Stream 做二次处理
  • 注意避免重复计算——不要在去重前就 filter,否则可能把本该保留的首条记录过滤掉

相关文章

精彩推荐