ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

如果像 AI 一样写 Lambda(第 4 篇):聚合与收集

如果像 AI 一样写 Lambda(第 4 篇):聚合与收集 如果像 AI 一样写 Lambda(第 4 篇):聚合与收集(Stream 应用篇)一句话总结:流处理完总要收摊。Collectors.toList/joining/groupingBy/reduce是把流变回集合、字符串、Map、单值的四大收摊工具,它们本身就是::的重度用户。相关文档:《如果像AI一样写Lambda-第3篇-转换与过滤-通俗版.md》——先加工,再收摊。0. 比喻:收银台汇总写法比喻普通人的写法一个个手记,最后自己算总账函数式写法把汇总规则告诉收银机AI lambda 简写规则直接指到现成方法,比如求和用Integer::sum表达1. 流变 List:collect(toList)场景:加工完的流,装回一个 List。① 普通人的写法:for 循环逐个装ListStringresultnewArrayList();for(Stringname:names){if(name!null){result.add(name.trim());}}② 函数式写法:filter map collectListStringresultnames.stream().filter(name-name!null).map(name-name.trim()).collect(Collectors.toList());③ AI lambda 简写:全链路方法引用ListStringresultnames.stream().filter(Objects::nonNull).map(String::trim).collect(Collectors.toList());Collectors.toList()是固定搭配,AI 几乎不会去 new ArrayList 手抄。filter → map → collect三段式的组合正是第 3 篇两个 API 的串联。2. 流变字符串:joining场景:把列表拼成逗号分隔的字符串。① 普通人的写法:StringBuilder 手拼ListStringitemsArrays.asList(A,B,C);StringBuildersbnewStringBuilder();for(inti0;iitems.size();i){if(i0){sb.append(,);}sb.append(items.get(i));}Stringresultsb.toString();// A,B,C② 函数式写法:collect(joining)Stringresultitems.stream().collect(Collectors.joining(,));③ AI lambda 简写:先流式加工再拼接Stringresultnames.stream().filter(Objects::nonNull).map(String::trim).collect(Collectors.joining(,));补充:如果只是纯列表拼接(不加工),String.join(,, items)比 stream 更短;joining的舞台在先过滤、再转换、最后拼的组合拳里。3. 流变 Map:groupingBy场景:按某个规则把列表分组,变成 Map。① 普通人的写法:for 循环 computeIfAbsentMapString,ListStringgroupMapnewHashMap();for(Stringname:names){Stringkeyname.substring(0,2);// 按前两个字符分组groupMap.computeIfAbsent(key,k-newArrayList()).add(name);}② 函数式写法:groupingBy lambdaMapString,ListStringgroupMapnames.stream().collect(Collectors.groupingBy(name-name.substring(0,2)));③ AI lambda 简写:分组 计数一步到位MapString,Longcountsnames.stream().collect(Collectors.groupingBy(Function.identity(),Collectors.counting()));groupingBy的第二个参数可以继续嵌套收集器,统计、再映射都能一行完成,这是它被 AI 偏爱的原因。4. 流变单值:reduce场景:把一堆数合成一个结果(求和、求最大值)。① 普通人的写法:for 循环累加ListIntegernumsArrays.asList(1,2,3,4,5);intsum0;for(intn:nums){sumn;}② 函数式写法:reduce 完整 lambdaintsumnums.stream().reduce(0,(a,b)-ab);③ AI lambda 简写:多参数方法引用intsumnums.stream().reduce(0,Integer::sum);Integer::sum等价于(a, b) - Integer.sum(a, b)——方法引用同样支持多参数,只要参数个数对得上。求最大值同理:reduce(Integer::max)。5. 四大收摊工具对照表工具目标形态典型用途一句话记忆Collectors.toList()List过滤/转换后落盘流 → 列表Collectors.joining(,)String拼接展示流 → 字符串Collectors.groupingBy(...)Map分组统计流 → 分组reduce(0, Integer::sum)单值求和/求极值流 → 单值6. 陷阱:Collectors.toMap 重复 key 会炸groupingBy自动处理重复 key(合并成 List),但toMap不会:// ❌ 两个元素算出的 key 相同 → 抛 IllegalStateExceptionMapString,Stringmapnames.stream().collect(Collectors.toMap(name-name.substring(0,2),Function.identity()));// ✅ 必须给出冲突策略(k1, k2) - k2 表示后到的覆盖先到的MapString,Stringmapnames.stream().collect(Collectors.toMap(name-name.substring(0,2),Function.identity(),(k1,k2)-k2));不确定 key 是否唯一时,groupingBy永远比toMap安全。一页速记收摊四件套:流变 List 用toList,变字符串用joining,变 Map 用groupingBy,变单值用reducefilter → map → collect是 AI 处理列表的标准三段式纯列表拼接用String.join(,, items),流式加工后才用joiningreduce(0, Integer::sum) 求和,reduce(Integer::max) 求最大值方法引用支持多参数:(a, b) - a bInteger::sumtoMap遇重复 key 会抛异常,必须写第三参(k1, k2) - k2;不确定唯一就用groupingBy
返回列表