【Easylive】项目常见问题解答(自用&持续更新中…) 汇总版
在 saveVideoInfo
方法中,stream()
方法被多次用于对集合进行函数式操作。下面我将详细解析每个 stream()
的使用场景和实现逻辑。
1. 将上传文件列表转为Map
Map<String, VideoInfoFilePost> uploadFileMap = uploadFileList.stream().collect(Collectors.toMap(item -> item.getUploadId(), // Key映射函数Function.identity(), // Value映射函数(data1, data2) -> data2 // 合并函数(解决键冲突)));
解析:
• 目的:将 List<VideoInfoFilePost>
转换为 Map<String, VideoInfoFilePost>
,以便通过 uploadId
快速查找文件
• 分解:
1. `uploadFileList.stream()` - 将列表转为流
2. `Collectors.toMap()` - 收集器,将流元素转为Map◦ 第一个参数 `item -> item.getUploadId()`:指定使用 `uploadId` 作为Map的键◦ 第二个参数 `Function.identity()`:使用元素本身作为Map的值◦ 第三个参数 `(data1, data2) -> data2`:如果键冲突(相同uploadId),保留后面的值
等价传统写法:
Map<String, VideoInfoFilePost> uploadFileMap = new HashMap<>();
for (VideoInfoFilePost item : uploadFileList) {uploadFileMap.put(item.getUploadId(), item);
}
2. 筛选新增文件
addFileList = uploadFileList.stream().filter(item -> item.getFileId() == null).collect(Collectors.toList());
解析:
• 目的:从上传文件列表中筛选出新增的文件(fileId
为null的文件)
• 分解:
1. `uploadFileList.stream()` - 创建流
2. `.filter(item -> item.getFileId() == null)` - 过滤条件
3. `.collect(Collectors.toList())` - 收集为List
等价传统写法:
List<VideoInfoFilePost> addFileList = new ArrayList<>();
for (VideoInfoFilePost item : uploadFileList) {if (item.getFileId() == null) {addFileList.add(item);}
}
3. 提取待删除文件的ID列表
List<String> delFileList = deleteFileList.stream().map(item -> item.getFileId()).collect(Collectors.toList());
解析:
• 目的:从待删除文件列表中提取所有 fileId
组成新列表
• 分解:
1. `deleteFileList.stream()` - 创建流
2. `.map(item -> item.getFileId())` - 映射转换,从对象中提取 `fileId`
3. `.collect(Collectors.toList())` - 收集为List
等价传统写法:
List<String> delFileList = new ArrayList<>();
for (VideoInfoFilePost item : deleteFileList) {delFileList.add(item.getFileId());
}
4. 提取待删除文件的路径列表
List<String> delFilePathList = deleteFileList.stream().map(item -> item.getFilePath()).collect(Collectors.toList());
解析:
• 目的:从待删除文件列表中提取所有 filePath
组成新列表
• 实现:与上一个例子类似,只是提取的是 filePath
而非 fileId
Stream API 核心概念总结
操作类型 | 方法 | 说明 | 示例 |
---|---|---|---|
创建流 | stream() | 从集合创建流 | list.stream() |
中间操作 | filter() | 过滤元素 | .filter(x -> x > 0) |
map() | 转换元素 | .map(x -> x.getName()) | |
终止操作 | collect() | 收集结果 | .collect(Collectors.toList()) |
forEach() | 遍历元素 | .forEach(System.out::println) |
为什么使用Stream API?
- 代码简洁:用声明式的方式表达复杂的数据处理逻辑
- 可读性强:链式调用更直观表达数据处理流程
- 并行处理:只需将
stream()
改为parallelStream()
即可实现并行 - 惰性求值:中间操作不会立即执行,提高效率
性能考虑
虽然Stream API很强大,但在简单循环就能完成的任务中,传统for循环可能更高效。Stream适合处理复杂的数据转换和过滤场景。
完整流程示例
假设有以下数据:
List<VideoInfoFilePost> uploadFileList = Arrays.asList(new VideoInfoFilePost("f1", "u1", "p1"), // fileId不为null,视为已有文件new VideoInfoFilePost(null, "u2", "p2"), // fileId为null,视为新增文件new VideoInfoFilePost(null, "u3", "p3") // fileId为null,视为新增文件
);
执行:
List<VideoInfoFilePost> addFileList = uploadFileList.stream().filter(item -> item.getFileId() == null).collect(Collectors.toList());
结果:
addFileList = [VideoInfoFilePost(null, "u2", "p2"),VideoInfoFilePost(null, "u3", "p3")
]
通过Stream API,我们简洁地实现了数据筛选和转换,代码更加清晰易读。