Apex 控制流语句:条件判断、Switch 分支与循环完全指南
Apex 控制流语句完全指南:深入详解 if-else 条件判断(else与最近if配对)、switch/when多值分支(支持Integer/Long/String/sObject/Enum/null值、无fall-through机制)、when块三种形式(字面量多值/sObject类型隐式instanceof/枚举值)、when else防御性编程(托管包枚举兼容性)、五种循环(do-while始终至少执行一次/while可能零次/传统for五步执行/列表集合迭代for/SOQL for双格式)、break/continue循环控制及集合迭代安全模式(临时集合模式避免并发修改)。
本课程共有 17 个章节
大家好,咱们今天来聊聊Apex里怎么控制代码的执行流程。简单说,正常情况下代码是一行一行往下跑的,但如果你想让程序根据不同条件走不同分支,或者重复做某件事,就需要用到控制流语句了。 这一章会把这些工具都给你讲透。首先是最常用的if-else,它跟Java里的用法基本一样,条件成立就做这个,不成立就做那个。然后是Switch语句,它专门用来处理多个分支的情况,特别适合判断sObject对象类型或者枚举值,比用一串if-else清爽多了。 接下来是循环部分,Apex支持五类循环。do-while和while是经典的先判断或后判断循环;传统的for循环用计数器控制次数;还有专门用来遍历列表和集合的迭代for循环,写起来很方便;最后一个是Apex独有的SOQL for循环,可以从数据库分批取数据,对处理大批量记录特别友好。 循环里还少不了break和continue这两个控制帮手,一个直接跳出循环,一个跳过本轮继续下次。另外要小心,在循环里修改你正在遍历的集合时,有几个固定模式,乱改容易出现不可预知的问题,后面我们会细说。 把这些控制流学扎实,你就能写出很灵活的自动推理程序了。有什么问题随时问,咱们一点一点吃透。
同学们,我们今天来看一看Apex里的控制流语句。简单来说,程序里的代码通常是按照出现的顺序,一行接一行地执行,就像我们看书一样,从第一行读到最后一行。但很多时候,我们需要根据不同的情况走不同的路,或者重复做某件事,这时候就要用到控制流了。 Apex提供了几种主要的控制流结构,很方便。首先是条件判断,最常用的就是 if-else 语句。它的写法和 Java 里几乎一模一样。如果条件成立,就执行一段代码;如果条件不成立,可以走 else 后面的另一段代码。这样你的程序就能做出选择了。 接着是 Switch 语句。它用来测试一个表达式,看看它的值跟后面列出来的哪个选项匹配。匹配上了,就跳转到对应的分支去执行。如果都不匹配,还可以设一个默认的分支。这在需要判断多个固定取值的时候非常清晰。 然后我们来看看循环。Apex支持五种类型的循环,可以让你重复执行一段代码,直到条件不再满足为止。 第一种是 do-while 循环,它会先执行一次循环体,然后再检查条件,所以循环里的代码至少会运行一次。 第二种是 while 循环,它先检查条件,条件满足才执行循环体,可能一次都不执行。 第三种是传统的 for 循环,就是我们熟悉的 for(初始化;条件;步进)那种结构,用一个计数器来控制循环次数。 第四种是列表或集合的迭代 for 循环,可以直接遍历一个列表或者集合里的每一个元素,写法很简洁,比如 for(变量 :列表)这样。 最后一种很有Apex特色的,就是 SOQL for 循环。它专门用来处理查询结果的,可以直接把数据库查询返回的记录一条一条拿出来处理,甚至还能在循环里分批获取数据,提高效率。 不论你用的是哪种循环,都可以在循环体内部使用 break 和 continue 来控制流程。break 是直接跳出整个循环,后面的循环不再执行;continue 是结束当前这一次迭代,跳过下面的代码,直接开始下一轮循环。这两个关键字在处理复杂逻辑时非常有用。 好了,刚才说的就是 if-else、Switch 语句,以及 Apex 里五种循环的基本概念。把这些控制流结构掌握好,你就能写出更灵活、更高效的程序逻辑了。
好,接下来我们聊聊条件语句,也就是 if-else 语句。这个概念在 Apex 里和 Java 差不多,如果你学过 Java,那这部分会感觉非常熟悉。 简单来说,就是让程序根据某个条件来决定执行哪段代码。这个条件必须是一个布尔值,就是要么真要么假。如果条件是真的,就执行 if 后面大括号里的代码;如果条件是假的,并且你写了 else 部分,那就执行 else 后面大括号里的代码。当然,else 部分不是必须的,你可以完全不用它,只使用 if 来判断。 有一点特别重要,就是当你有多个 if 嵌套或者连着写的时候,else 总是和它前面最近的、还没有配对的 if 结合在一起。也就是说,else 不会跳过一个 if 去和更远的 if 匹配,这一点在逻辑上要理清楚,避免写出意想不到的结果。 比如,如果我有两个 if 紧接着,然后写了一个 else,这个 else 只属于离它最近的那个 if。这种设计跟 Java 完全一样。所以理解了这个规则,你就能写出清晰的条件分支了。 好了,这就是条件语句的基本要点。你只要记住,if 根据布尔值走分支,else 可选,而且它只粘着最近的 if。这样用起来就不会迷糊了。
好,我们来看一下Apex里面的条件语句。这个其实跟你熟悉的Java几乎是一模一样的,所以如果你写过Java,那这里就非常轻松了。 首先最基本的就是if语句。它后面跟一个小括号,里面放一个布尔条件。什么叫布尔条件呢?就是结果只能是true或者false的东西。比如一个比较:分数大于60,或者一个布尔变量本身。 如果这个条件是true,那么就会执行紧跟在它后面的那一段代码块。如果条件是false,就不会执行这个块,而是跳到else那里继续。当然,else这一块是可选的,你可以写,也可以完全不写。 还有一点要注意:else总是跟它上面离得最近的那个if配对,这个跟其他语言一样,不要弄混了。 语法上,如果你的if或else后面只有一条语句,那你可以不用写大括号。但是,如果有多条语句,一定要用大括号把它们包起来,不然只有第一条算在if里面,后面会出问题。为了代码清晰,很多开发者就算只有一条语句也会加大括号,是个好习惯。 如果你的逻辑比较复杂,不止两种情况怎么办?很简单,用else if把多个条件串起来。像这样:if – else if – else if – else,最后那个else兜底,处理所有不满足前面条件的情况。 最后再强调一遍:条件必须是一个布尔值。你不能写if(变量),除非这个变量本身就是Boolean类型。必须是一个能算出true或false的表达式,这一点和Java完全一样。 那这节课关于条件语句的这些基本规则,大家理解了之后,写逻辑判断就没什么问题啦。
好,现在我们来看一个叫“Switch声明”的东西。你可以把它理解成一种更简洁的条件判断方式,专门用来检查一个表达式的值是不是等于几个可能的情况之一,然后根据不同情况执行不同代码。 举个例子,假设我们有个变量存的是星期几,你想根据它是星期一、星期二还是其他日子做不同的事,那用 Switch 就会比写一大堆 if-else 更清晰。 Apex 里的 Switch 支持好几种数据类型,比如整数、长整数、字符串,还有我们前面学过的 sObject 和枚举类型。你只要写一个表达式,然后列出几个可能的值,每个值后面跟着要执行的代码块。 有一点要特别注意:在 Apex 里,Switch 是没有“fall-through”的——意思就是说,当一个匹配的代码块执行完之后,程序会直接跳出整个 Switch,不会自动跑到下一个 case 里去。这样逻辑更安全,不会因为漏写 break 而出错。 所以记住:Switch 是分支判断的好帮手,支持多种类型,而且每个分支执行完会自动退出。
同学们好,我们来看一下 Apex 里的 switch 语句,它很像一个多路选择的开关。 switch 会先计算一个表达式的值,然后拿这个值去跟下面的 when 值做匹配。匹配上哪一个,就执行对应的代码块。如果所有 when 值都没匹配上,就会去执行 when else 代码块(相当于别的语言里的 default)。要是你压根没写 when else,那整个 switch 就什么都不做,安安静静地跳过。 特别要注意一个事儿:Apex 的 switch 没有“故障穿透”——也就是说,一个代码块执行完之后,会自动退出 switch,不需要你再去写 break 语句,这跟 Java 或 C 语言不一样。 那表达式可以是哪些类型呢?可以是 Integer、Long、字符串也就是 String、枚举类型 Enum,还可以是 sObject 类型。 when 值也可以很灵活:可以写单个值,也可以用逗号隔开写多个值,只要表达式等于其中任意一个就会匹配。如果你在 switch 上用的是 sObject 类型的表达式,when 值还可以直接写一个 sObject 类型的变量名,系统会按引用相等来判断是不是同一个对象。 好,这就是 switch 语句的基本规则,记清楚这几点,你在写多分支逻辑的时候就会非常顺手了。
同学们,这一小节课我们来聊聊 Apex 里 switch 语句中 when 块的匹配值到底是怎么回事儿,搞清楚它有哪些写法,以及需要注意的规则。 首先,每个 when 块后面都需要跟着一个值,用来和 switch 那个表达式的结果进行比较。这个值呢,可以有三种常见的形式。 第一种,直接写一个具体的字面量,比如数字 5,或者字符串 'hello'。这时候就写成 `when 5 { }` 这样。你还可以在一个 when 里用逗号隔开,列出好几个字面量,让这个块能够匹配多种不同的值。比方说 `when 1, 2, 3 { }`,就表示只要表达式的值是 1、2 或者 3,都会进到这个大括号里执行。 第二种形式呢,是用来匹配 sObject 类型的。写法是 `when 后面跟一个 SObjectType 标识符`,比如 `when Account.SObjectType { }`。当你需要根据不同的对象类型执行不同逻辑的时候,这个特别方便。 第三种就是枚举匹配了,直接写 `when 枚举值 { }`。比如你有一个表示状态的枚举,就可以写 `when Status.Approved { }` 来匹配那个已批准的状态。 除了这几种,还有一个很重要的点:null 也是合法的匹配值。也就是说你可以写 `when null { }` 来处理表达式为空的情况,这对所有类型都适用。 接下来两个规则千万要记住:第一,所有 when 里写的值必须是不重复的,每个字面量只能在一个 when 分句里出现一次。比如你没法在两个不同的 when 块里都写上文本 'x',那样编译会报错。第二,switch 语句最多只会执行一个 when 块。只要从上往下找到第一个匹配的块,进去执行完就跳出去了,后面的 when 块就算也匹配,也会被忽略。所以不用担心会执行多次。 这样一来,when 块的三种写法、连同一个空值匹配,还有唯一性和单次匹配这两条规则,就构成了 Apex switch 里匹配值的基础。你只要记住这些,写 switch 的时候心里就有数了。好了,这个概念我们就讲到这里,是不是一下就清楚多啦?
好,我们来看看Switch语句里的when else块。你可以把它理解成一个“兜底”的选项,就像告诉程序:如果前面列出的所有情况都不匹配,就执行这里的代码。 Salesforce特别建议你在处理枚举类型的时候,一定要加上when else。为什么呢?因为枚举的值可能会变。比如,你可能引用了托管包里定义的枚举,如果将来这个包升级了,里面新增了几个枚举值,而你的Switch里没有对应这些新值的when分支,代码就不知道该怎么办了,可能会抛出异常,结果就不符合预期了。 而如果你提前准备了一个when else块,就能把所有这些意外的新值都接住,让程序继续安全地运行下去,至少不会因为没处理到而崩溃。 还有一点要注意:如果你要写when else块,它必须是Switch语句里的最后一块,不能写在前面的when之间,就像打扫战场的最后一步一样。 这就是when else块的作用,简单说就是“其他所有情况”的保险。
同学们好,今天我们来看Apex里一个很好用的控制结构——switch语句,弄清楚它的一些细节,能让你写代码时更得心应手。 首先,switch能判断什么类型的值呢?最常用的是整数、长整数和字符串这几种。而且你可以在when子句里直接写上具体的值去匹配,比如数字3,或者字符串'apple'。这里要特别注意,字符串是区分大小写的,'orange'和'ORANGE'会被当成两个完全不同的值,这点千万别搞混了。 因为Apex里所有类型都可以是空的,所以when后面的值也可以写成null,用来匹配空值的情况。 接着,一个和其他语言很不一样的地方:Apex的switch不会“失败”,或者说不存在“穿透”的问题。什么意思呢?就是你不需要在每个when代码块的末尾加break,程序执行完匹配的那个分支后,就会自动跳出整个switch,不会跑到下一个分支里去。不过,一个when子句可以同时匹配多个值,用逗号隔开就行,这样当需要多个值走同一段逻辑时,你就不用重复写很多个when了。 另外,你还可以嵌套switch。也就是说,在一个when分支里面再写一个完整的switch语句,这样就能根据不同的条件,进一步分出多条执行路径,处理更复杂的逻辑。 还有一个小技巧:switch后面那个括号里,不仅可以放一个变量,也可以直接放一个方法调用。比如,你有个函数返回某个状态,你就可以直接switch on这个函数的返回值,让代码更加简洁。 好了,记住这些点,写switch的时候就能少踩坑了。下节课我们继续聊Apex的其他实用技巧,同学们再见!
同学们,今天咱们要讲的这个知识点,有点像是给代码做了一次“整形手术”。以前我们在 Apex 里处理不同类型的 sObject 时,比如从某个通用记录变量里,既可能是 Account,也可能是 Contact,还可能是 null,你通常要写一长串 if-else,里面套着 instanceof 检查,然后再手动强制转换类型,代码既啰嗦又容易出错。 现在呢,Apex 给我们提供了一个更优雅的写法——你可以直接对一个 sObject 变量使用 ,switch, 语句。Slide 上把它叫做“打开 sObject 值”,其实意思就是,用 switch 去匹配这个 sObject 的实际类型。注意,这里可能是笔误写成了 sBody,实际我们讨论的都是 sObject。 这个写法,能隐式地帮你完成两件事:一个是 instanceof 类型检查,另一个是自动的强制转换,所以你不用再写又长又臭的 if-else 链了。 怎么用呢?在 when 子句里,你可以直接声明一个带类型的变量,比如 `when Account a`,它就创建了一个 Account 类型的变量 a,并且已经帮你把原来的 sObject 自动转成 Account 了。这样你在这个 when 块里面,可以马上用 a.Name、a.AccountNumber 这些字段,非常舒服。每个 when 块也只能指定一种 sObject 类型,结构清清楚楚。 而且,这个 switch 还能专门处理 null 的情况,写一个 `when null` 就可以了,这样即使是个空记录,你也能妥善处理,不会被遗漏。 举个简单的例子,假设有一个 sObject 变量 `record`,它可能是 Account、Contact,或者是 null。以前你要这样写: ```apex if (record instanceof Account) { Account acc = (Account) record; // 处理 Account } else if (record instanceof Contact) { Contact con = (Contact) record; // 处理 Contact } else if (record == null) { // 处理空值 } ``` 用新的 switch 写法,就变成了: ```apex switch on record { when Account a { // 直接使用 a,它是 Account 类型 System.debug(a.Name); } when Contact c { // 直接使用 c,它是 Contact 类型 System.debug(c.LastName); } when null { // 处理空值 } } ``` 是不是瞬间清爽了很多?这就好比,你走进一个房间,switch 帮你自动识别来客身份,并且递上对应的名片,你直接握手就好了,不需要再自己验明正身再去要名片。所以这个特性,能大大提高代码的可读性,也减少了类型转换带来的潜在风险。在写触发器或者通用工具类时,特别有用。 好了,这一页的核心就是:通过 switch 来匹配 sObject 类型,让代码告别冗长的 instanceof 和强转,更简洁、更安全。大家可以在练习中试一试,习惯之后,你会爱上这种写法的。
我们来看一个关于Switch语句处理枚举的小知识点。 在Apex里,如果你用枚举类型来做Switch判断,其实语法上并不强制要求你写`when else`这个兜底分支。也就是说,就算你没有把枚举里所有可能的值都列出来,代码也能编译通过。 但是老师还是建议你,最好写上`when else`。为什么呢?因为你可以在一个`when`块里一次性匹配多个枚举值,用逗号隔开就行。比如,`when SPRING, SUMMER`,这样只要值是春天或者夏天,都会进这个分支来处理。 真正需要注意的场景是,当你使用的是来自托管包里的枚举。你想想看,托管包是别人开发的,说不定哪天就更新了,往枚举里加了几个新值。如果你的Switch没写`when else`,那遇到这些新值的时候,你的代码就懵了,不知道该怎么办,可能就出了意外。 所以你只要加上一个`when else`,就能主动兜底,把所有你没预料到的新值都稳稳接住,提前做好保护。这样代码以后就耐用多了,不会因为别人更新个包就崩溃。这是一个很好的习惯。
好,同学们,我们接着往下看,现在来聊聊循环。循环其实就是让一段代码重复执行,直到满足某个条件才停下来。在Apex里,我们有五种循环方式,可以应对各种重复操作的场景。 第一种是 ,do-while 循环,,它先执行一遍代码块,然后再检查条件,所以至少会跑一次。第二种是 ,while 循环,,它正好反过来,先判断条件,满足才执行,可能一次都不跑。第三种是,传统的 for 循环,,就是我们熟悉的带初始化、条件判断和迭代步进的那种写法,适合需要精准控制次数的场景。第四种是,列表或集合的迭代 for 循环,,它用来直接遍历集合里的每一个元素,写法非常简洁。第五种是,SOQL for 循环,,专门用来处理查询返回的大量记录,它能分批取数据,既高效又省内存。 所有这五种循环里,还都支持两个特别重要的控制命令:,break, 和 ,continue,。 break 是直接跳出整个循环,后面的循环就不跑了;而 continue 只是跳过当前这一次循环,直接开始下一次迭代。这两个小工具能帮我们灵活地控制循环的运行流程,大家在实际编码时经常会用到。 现在大家脑子先有个概念,后面我们会结合代码例子一个个细讲,这样印象会更深刻。
同学,咱们来看看 Apex 里的 do-while 循环。 你可以这样理解:它就像一个“先干活儿,后问话”的循环。只要一个布尔条件保持为 true,它就会反复执行一段代码。但跟 while 循环不一样的是,它直到第一次执行完循环体之后,才去检查那个条件是不是 true。所以,里面的代码块至少会被运行一次,哪怕条件一开始就是假的。 这点跟 Java 里是完全一样的,没什么区别。而且在 do-while 循环里,不管代码块只有一行还是很多行,你都必须得用花括号把它包起来,这个是强制要求。 那你什么时候用它呢?很简单,就是当你需要保证循环体至少执行一次,然后再根据条件决定要不要继续的时候。比如,你可能需要先让用户输入一次数据,然后再判断输入是否有效,无效的话就重复提示,这种场景就特别适合 do-while。 好,这部分就讲到这里,咱们继续看后面的内容。
我们来聊聊Apex里的while循环。 你可以把它想象成一个“先问再做”的循环。程序每执行一次循环之前,都会先检查一个布尔条件,只有这个条件是真的,它才会运行花括号里的代码。一旦条件变成假,循环就立刻停下来了。 这就意味着,如果第一次检查时条件就是假的,那循环里的代码可能一次都不会执行。这和do-while循环不一样,do-while是先做再问,所以至少会执行一次。 还有一个书写上的小细节:如果循环里只有一条语句,花括号可以省略;但如果有好几条语句,那就必须用花括号把它们包起来,不然代码会出错。 所以什么时候该用while呢?就是当你需要在做事之前先判断一下,而且有可能根本不需要执行循环体的时候。比如你从一个列表里读数据,但列表可能是空的,那用while就很合适。它会先检查“列表里还有数据吗”,如果没有,就直接跳过,干净利落。
好,我们继续往下看。接下来要讲的是Apex里面一种很基本的循环结构——传统for循环。如果你以前写过Java或者其他类似的编程语言,看到这种写法肯定特别熟悉,因为它们的语法几乎是一样的。 那这个传统for循环到底是怎么工作的呢?我们可以把它的执行过程拆成四步,每一步都很清晰。 第一步,先执行,初始化语句,。在for循环的小括号里,最前面那一部分就是初始化。你可以在这里声明一个变量,也可以同时声明好几个,用逗号隔开。这一步,只会在循环最开始的时候执行一次,。 第二步,检查,退出条件,。初始化做完之后,运行时会去看那个判断条件。如果条件的结果是true,循环就继续往下走;如果是false,那循环就直接结束,整个for循环就执行完了。 第三步,如果条件为true,就执行,循环体,,也就是大括号里面那一段代码块。你需要重复做的事情,都写在这里。 第四步,循环体跑完之后,会去执行,增量语句,。这通常就是让变量加一或者减一,用来推动循环往前走,避免死循环。 执行完增量语句之后,它不会停下,而是回到第二步,再去检查退出条件。如果条件还成立,就继续跑一遍循环体,再增量,再检查…… 一直重复这个过程,直到某一次条件变成false,循环才退出。 你看,这个流程把“初始化、判断、执行、更新”分得很清楚,每一步都交给你来控制。所以传统for循环最大的好处就是,给了我们细粒度的控制能力,,你可以很自由地决定循环从哪里开始、怎么结束、以什么步长往前走。特别是当你需要跳过某些元素,或者要倒着遍历,这种写法就非常顺手。 好,关于传统for循环的执行步骤,我们就先说到这里。有了这个基础,后面你写循环的时候心里就有数了,能够很清楚地知道每一轮到底发生了什么。
同学们,之前我们学过了Apex里循环的基本写法。今天咱们再深入一点,把循环用在列表、集合,还有SOQL查询上的几个要点捋一捋,这些细节虽然小,但写代码时很容易踩坑。 首先,当我们用for循环去遍历一个列表或集合的时候,比如 `List<Account>` 或者 `Set<String>`,你声明的那个循环变量,它的类型必须跟集合里存放的元素类型完全一致。如果是基本类型,像String、Integer这些,变量类型就得是相同的String或Integer;如果是sObject,比如Account、Contact,变量类型也必须是那个sObject。举个例子呀,你有一个 `List<String>` 叫names,那你这么写 `for (String n : names)` 就是对的,循环变量n的类型就是String。你要是写成 `for (Object n : names)`,虽然Object是所有类的父类,但这种直接遍历列表的写法里Apex不允许,它会报类型不匹配的错。集合里是啥,你循环变量就声明成啥,简单直接。 接着说SOQL for循环,这是我们经常会用到的,直接在一个for循环里写入SOQL查询。写法像这样: ```apex for (Account acc : [SELECT Id, Name FROM Account]) { // 处理每条Account记录 } ``` 或者你也可以用一个列表变量来接收查询结果: ```apex for (List<Account> accList : [SELECT Id, Name FROM Account]) { // 这里accList是每次返回的一组记录,可以批量处理 } ``` 关键点在于,循环变量(单个sObject或者sObject的列表)的类型,也必须跟你查询返回的sObject类型相同。比如你查询的是Account,那变量就是Account或 `List<Account>`;查询的是Contact,就是Contact或 `List<Contact>`。如果不匹配,编译都过不去。 最后,还有个花括号的小规矩。如果for循环的代码块里只有一句代码,你可以省略花括号,像这样: ```apex for (Account a : accList) System.debug(a.Name); ``` 但如果里面有多于一条语句,比如既要调试输出又要更新字段,那你就必须用花括号把代码块包起来,不然Apex只把紧跟的第一行当成循环体,后面就不认了。其实为了代码清晰,也建议大家哪怕只有一行也加上花括号,养成好习惯,以后改代码加语句不容易出错。 好了,这几个点记住了,以后写循环就更顺了。咱们接着看后面的内容。
同学们,咱们今天来看一个在写 Apex 代码时特别容易踩的坑,也是面试和实际开发里经常被考察的知识点:,在循环里修改集合,。 你想象一个场景:手里有一串客户名单,你想把里面不活跃的客户直接删掉。很可能顺手就写一个 for 循环,在里面用 `list.remove()`,对吗?结果一执行,系统直接就报错了,告诉你“不能修改集合”。这是为啥呢? 因为 Salesforce 为了保证数据的完整性和循环的稳定性,,明确禁止在迭代一个集合的同时,往里添加或者删除元素,。不管你是用列表、集合还是映射,都会遇到同样的问题。那该怎么做呢?别急,老师教你几招非常简单的处理模式。 ,如果你想在循环的时候添加元素,,千万别直接往当前集合里塞。办法是:先准备一个临时的小盒子——可以是一个临时的列表、临时集合或者临时映射。把需要新增的元素先装进这个临时盒子里。等整个循环跑完了,再用 `addAll` 或 `putAll` 一次性把临时盒子里的东西倒进原始集合。这样就分成了两个独立步骤,互不影响。 ,如果是想在循环里删除元素,,针对列表,有两种常用做法。第一种是新建一个列表,然后在循环里判断,把你要,保留,的那些元素复制到新列表里,循环结束以后直接用新列表替换掉原来的。这样你压根就没动正在迭代的旧列表。第二种是把想要删除的元素先记录到一个临时列表里,等循环结束后,再拿着这个“删除清单”一次性地从原列表里删掉。对于映射和集合呢,就更简单了:循环时把想要删除的,键,存到一个临时列表里,等迭代完,再用这个键列表去原集合里逐一删除。 说到这儿,还要特别提醒一个性能细节。`List.remove` 这个方法的时间复杂度是,线性,的,也就是说,如果要删的元素在列表很靠前的位置,后面所有元素都得往前挪。假如你在一个大循环里频繁地调 `remove`,不仅慢,还会消耗大量 CPU 资源,很容易就撞上 Salesforce 的调控器限制。所以,更推荐的上策是,尽量构造新集合去保留你需要的数据,,或者把删除操作集中到循环外批量执行,这样才能保证代码又稳又高效。 总结一下,核心原则就一句话:,迭代时不碰原集合,想添加就暂存暂存再合并,想删除就标记标记后集中删,或者新建集合留你想留的。, 记住这个心法,你以后再处理集合操作就能避开一堆奇怪错误了。 好了,今天这一页的重点你掌握了吗?下回写循环的时候一定留个心眼哦。