本文目录导读:

不支持。
Laravel 的 Collection 类(Illuminate\Support\Collection)不支持惰性求值,当你调用 filter、map、sort 等方法时,它会立即执行并返回一个新的完整集合。
为什么说它不支持?
- 即时执行:
Collection的所有中间操作(->filter()->map())都会立即遍历整个数组并生成新集合。 - 内存占用:如果数据量很大(10 万条),所有中间结果都会被创建并保存在内存中。
示例(验证):
$collection = collect([1, 2, 3, 4, 5]);
$result = $collection
->filter(function ($item) {
echo "filter: $item\n";
return $item > 2;
})
->map(function ($item) {
echo "map: $item\n";
return $item * 10;
});
// 输出:
// filter: 1
// filter: 2
// filter: 3
// filter: 4
// filter: 5
// map: 3
// map: 4
// map: 5
可以看到 filter 和 map 是各自完整执行一轮,而不是按需逐个求值。
那 Laravel 有惰性集合吗?
有,但需要显式使用 LazyCollection。
LazyCollection(Illuminate\Support\LazyCollection)是专门为惰性求值设计的版本。- 它继承自
Collection,但底层使用生成器(Generator) 实现。 - 只有当你真正使用(遍历、
toArray()、获取首元素)时,才会逐个计算。
LazyCollection 示例:
$lazy = LazyCollection::make(function () {
for ($i = 1; $i <= 5; $i++) {
yield $i; // 生成器,按需产出
}
});
$result = $lazy
->filter(function ($item) {
echo "filter: $item\n";
return $item > 2;
})
->map(function ($item) {
echo "map: $item\n";
return $item * 10;
});
// 此时还未执行任何代码!
// 当开始遍历时才逐个求值:
foreach ($result as $value) {
echo "value: $value\n";
}
// 输出顺序(注意是交错执行的):
// filter: 1
// filter: 2
// filter: 3
// map: 3
// value: 30
// filter: 4
// map: 4
// value: 40
// filter: 5
// map: 5
// value: 50
什么时候应该用 LazyCollection?
| 场景 | 推荐 |
|---|---|
| 小数据集(< 1000 条) | 普通 Collection |
| 大数据集(数万以上) | LazyCollection |
| 处理无限流(文件行、数据库游标) | LazyCollection |
| 需要缓存中间结果,多次遍历同一集合 | 普通 Collection(惰性会重复计算) |
| 调试方便性 | 普通 Collection(立即执行,问题更直观) |
| 特性 | Collection |
LazyCollection |
|---|---|---|
| 求值策略 | 热切求值(Eager) | 惰性求值(Lazy) |
| 内存占用 | 全部元素 | 仅当前处理的元素 |
| 性能 | 适合小数据集 | 适合大数据集/无限流 |
| 使用方式 | collect([...]) |
LazyCollection::make(...) |
简单记忆:如果你需要处理大型 CSV 文件、API 分页数据或数据库游标,用 LazyCollection;日常小数据操作,普通 Collection 更简单直接。