java中arraylist通过stream实现复杂分组的核心是collectors.groupingby的嵌套与组合,配合自定义分类器、下游收集器(如mapping、filtering、summingint等)及多级分组逻辑。

Java 中 ArrayList 通过 Stream 实现复杂分组,核心是 Collectors.groupingBy 的嵌套与组合,配合自定义分类器、下游收集器(如 mapping、filtering、summingInt 等)以及多级分组逻辑。
基础分组:按单个字段分类
最常见的是按对象某个属性分组,比如将用户列表按城市分组:
List<user> users = Arrays.asList(
new User("张三", "北京", 25),
new User("李四", "上海", 30),
new User("王五", "北京", 28)
);
Map<string list>> byCity = users.stream()
.collect(Collectors.groupingBy(User::getCity));
// 结果:{"北京": [张三, 王五], "上海": [李四]}
</string></user>
多级分组:嵌套 groupingBy
实现“先按城市,再按年龄区间”这类两级分组,用 groupingBy 嵌套即可:
Map<string map list>>> grouped = users.stream()
.collect(Collectors.groupingBy(
User::getCity,
Collectors.groupingBy(u -> u.getAge()
<ul>
<li>外层 key 是城市,内层 key 是年龄段</li>
<li>注意第二参数是下游收集器,不是另一个 lambda</li>
</ul>
<h3>带聚合的分组:统计、映射、去重</h3>
<p>不只保留原始对象,还能做转换或计算:</p><div class="aritcle_card flexRow artxards">
<div class="artcardd flexRow">
<a class="aritcle_card_img" rel="nofollow" href="/xiazai/gongju/2847" title="OpenJDK 24"><img
src="https://img.php.cn/upload/manual/001/431/639/6ad0919a12f37751.png" alt="OpenJDK 24" onerror="this.onerror='';this.src='/static/lhimages/moren/morentu.png'" ></a>
<div class="aritcle_card_info flexColumn">
<a rel="nofollow" href="/xiazai/gongju/2847" title="OpenJDK 24" class="overflowclass">OpenJDK 24</a>
<p class="overflowclass"></p>
</div>
<a rel="nofollow" href="/xiazai/gongju/2847" title="OpenJDK 24" class="aritcle_card_btn flexRow flexcenter"><b></b><span>下载</span>
</a>
</div>
</div>
<ul>
<li>
<strong>统计每组人数</strong>:<code>Collectors.counting()</code>
</li>
<li>
<strong>提取某字段并去重</strong>:<code>Collectors.mapping(User::getName, Collectors.toSet())</code>
</li>
<li>
<strong>求年龄总和</strong>:<code>Collectors.summingInt(User::getAge)</code>
</li>
<li>
<strong>只保留满足条件的元素</strong>:<code>Collectors.filtering(u -> u.getAge() > 26, Collectors.toList())</code>
</li>
</ul>
<p>例如:按城市分组,并统计各城市 25 岁以上用户姓名集合:</p>
<pre class="brush:java;toolbar:false;">Map<string set>> cityToNames = users.stream()
.filter(u -> u.getAge() > 25)
.collect(Collectors.groupingBy(
User::getCity,
Collectors.mapping(User::getName, Collectors.toSet())
));
</string>
自定义分组逻辑:用 Function 或 if-else 拆分
当分组规则较复杂(如按分数段、状态组合、多条件判断),可写一个明确的分类方法:
private static String getCategory(User u) {
if (u.getAge() > byCategory = users.stream()
.collect(Collectors.groupingBy(Main::getCategory));
也可用 lambda 内联表达,但建议提取方法提升可读性与复用性。
关键点在于理解 groupingBy 的三个重载版本,尤其是带下游收集器的二参/三参形式;合理组合 mapping、filtering、collectingAndThen 等,就能应对绝大多数业务分组场景。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










