☰
如果像 AI 一样写 Lambda(第 3 篇):转换与过滤
2026/9/30 7:21:51 网站建设 项目流程

如果像 AI 一样写 Lambda(第 3 篇):转换与过滤(Stream 应用篇)

一句话总结:map负责把元素"换件衣服",filter负责"筛掉不合格的",removeIf负责"当场赶走"。AI 会尽可能用::把三者写成一行。

相关文档:《如果像AI一样写Lambda-第1篇-函数式接口-通俗版.md》——map的地基是Function,filter的地基是Predicate。

0. 比喻:流水线工厂

写法比喻
普通人的写法老师傅手工:拿一件、加工一件、放一件
函数式写法流水线:每道工序贴一张"操作规则"
AI lambda 简写工序牌只写工具名:“打磨机”、“质检章”

1. map:逐个转换

场景:把一堆带空格的名字统一 trim 干净。

① 普通人的写法:for 循环逐个加工

Stringraw="AP S&P Partners, AP Tablet Partners, 2 Telco";String[]parts=raw.split(",");List<String>items=newArrayList<>();for(Stringpart:parts){items.add(part.trim());}

② 函数式写法:map + 完整 lambda

List<String>items=Arrays.stream(raw.split(",")).map(part->part.trim()).collect(Collectors.toList());

③ AI lambda 简写:方法引用

List<String>items=Arrays.stream(raw.split(",")).map(String::trim).collect(Collectors.toList());

String::trim很特殊:左边是类名而非实例。它等价于part -> part.trim(),流中的元素既是调用者又是参数。AI 看到"拿到元素 → 调它自己的无参方法"就会写类名::方法名。

2. filter:保留合格的

场景:滤掉列表里的 null。

① 普通人的写法:for + if 手工挑

List<String>result=newArrayList<>();for(Stringid:ids){if(id!=null){result.add(id);}}

② 函数式写法:filter + 完整 lambda

List<String>result=ids.stream().filter(id->id!=null).collect(Collectors.toList());

③ AI lambda 简写:方法引用

List<String>result=ids.stream().filter(Objects::nonNull).collect(Collectors.toList());

Objects::nonNull是 JDK 自带的官方方法引用,专门用来滤 null。这一步很关键:如果放任 null 流到下游(比如拼字符串),null 会被拼成 “null” 四个字符,埋下脏数据隐患。

3. removeIf:原地删除

场景:从名单里删掉所有排除项。

① 普通人的写法:迭代器边遍历边删

List<String>items=newArrayList<>(Arrays.asList("AP S&P Partners","Lenovo Global","2 Telco"));Iterator<String>it=items.iterator();while(it.hasNext()){Stringitem=it.next();if(EXCLUDE_NAMES.contains(item)){it.remove();}}

② 函数式写法:removeIf + 完整 lambda

items.removeIf(item->EXCLUDE_NAMES.contains(item));

③ AI lambda 简写:方法引用

items.removeIf(EXCLUDE_NAMES::contains);

removeIf的返回值是 boolean(是否真的删过元素),所以 AI 敢直接把它当条件用:

returnitems.removeIf(EXCLUDE_NAMES::contains)?String.join(",",items):original;

删过 → 返回重新拼接的结果;没删过 → 返回原值。一次遍历同时完成"判断 + 删除 + 汇报",这就是 AI 风格的典型表达。

4. 为什么增强 for 里不能直接删

// ❌ 会抛 ConcurrentModificationExceptionfor(Stringitem:items){if(EXCLUDE_NAMES.contains(item)){items.remove(item);}}

增强 for 本质是迭代器,遍历中修改集合会触发"并发修改"异常。传统写法必须用Iterator.remove(),而removeIf在内部替你安全地干了这件事——这就是它存在的意义。

5. map / filter / removeIf 对照表

API作用返回值元素去哪了
map逐个转换新 Stream换装后继续往下走
filter保留满足条件的新 Stream不合格的被丢弃
removeIf原地删除满足条件的boolean直接从原 List 里消失

map/filter是"无中生有"的流水线,不碰原集合;removeIf是"当场执法",直接改原 List。

6. 陷阱:removeIf 对不可变集合失效

// ❌ Arrays.asList 返回的是"只可改值、不可增删"的定长 ListList<String>fixed=Arrays.asList("A","B","C");fixed.removeIf("B"::equals);// 抛 UnsupportedOperationException

解法:先包一层new ArrayList<>(...)变成可变集合,再removeIf:

List<String>mutable=newArrayList<>(Arrays.asList("A","B","C"));mutable.removeIf("B"::equals);// ✅ 正常

一页速记

  • map(类名::无参方法)= 对每个元素调它的方法,如String::trim
  • filter(Objects::nonNull)= 滤掉 null 的官方姿势
  • removeIf(Set::contains)= 安全版"边遍历边删除",自带 boolean 返回值
  • 增强 for 里直接 remove 会炸,传统做法用Iterator.remove()
  • map/filter不碰原集合,removeIf直接改原 List
  • removeIf只能用于可变集合,Arrays.asList需要先new ArrayList<>()
  • lambda 体只有一句"调用现成方法" → 一律考虑改成::

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询