应将循环内不随变量变化的复杂方法调用提取到for-each外,重点优化三类:返回值稳定的(如list.size())、含重操作的(如db查询)、需多次链式调用的(如order.getitems().get(0).getprice())。

直接把循环体内反复调用的复杂方法结果提出来,放到 for-each 外面赋值一次,就能避开重复开销。
哪些方法调用值得抽取
不是所有方法都需要缓存,重点盯住三类:
- 返回值不随循环变量变化的方法(如
list.size()、config.getMaxRetry()、user.getProfile().getLevel()) - 内部含数据库查询、远程调用、正则匹配或深度遍历的方法
- 返回对象后还要链式调用多次(如
order.getItems().get(0).getPrice().multiply(taxRate))
典型低效写法与优化对比
❌ 低效(每次迭代都执行):
for (Order order : orders) {
if (order.getTotal() > config.getThreshold().doubleValue()) {
sendAlert(order);
}
}
这里 config.getThreshold() 每次都被调用,且返回 BigDecimal 后又转成 double —— 完全可复用。
✅ 优化(提前计算一次):
double threshold = config.getThreshold().doubleValue();
for (Order order : orders) {
if (order.getTotal() > threshold) {
sendAlert(order);
}
}
注意引用类型和副作用
抽取时要确认方法无副作用、线程安全、且返回值稳定:
- 若方法依赖当前时间(如
new Date())、随机数或外部状态,不能缓存 - 若返回的是可变对象(如
new HashMap()),缓存后在循环中修改会影响后续逻辑,需谨慎 - 多线程环境下,确保被抽取的对象是只读或线程安全的
嵌套结构中的分层抽取技巧
对深层对象访问,逐层提取比一次性写长链更清晰、更易调试:
UserConfig config = user.getConfig();
int maxRetries = config.getMaxRetries();
String fallbackUrl = config.getFallback().getUrl();
for (Request req : requests) {
if (req.getRetryCount() >= maxRetries) {
req.setFallbackUrl(fallbackUrl);
}
}
比起 user.getConfig().getMaxRetries() 写满整个循环体,分层命名让意图明确,也方便复用和单元测试。










