【Easylive】项目常见问题解答(自用&持续更新中...) 汇总版
在 saveVideoInfo
方法中,stream()
方法被多次用于对集合进行函数式操作。下面我将详细解析每个 stream()
的使用场景和实现逻辑。
1. 将上传文件列表转为Map
java
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),保留后面的值
等价传统写法:
java
Map<String, VideoInfoFilePost> uploadFileMap = new HashMap<>();
for (VideoInfoFilePost item : uploadFileList) {
uploadFileMap.put(item.getUploadId(), item);
}
2. 筛选新增文件
java
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
等价传统写法:
java
List<VideoInfoFilePost> addFileList = new ArrayList<>();
for (VideoInfoFilePost item : uploadFileList) {
if (item.getFileId() == null) {
addFileList.add(item);
}
}
3. 提取待删除文件的ID列表
java
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
等价传统写法:
java
List<String> delFileList = new ArrayList<>();
for (VideoInfoFilePost item : deleteFileList) {
delFileList.add(item.getFileId());
}
4. 提取待删除文件的路径列表
java
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适合处理复杂的数据转换和过滤场景。
完整流程示例
假设有以下数据:
java
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,视为新增文件
);
执行:
java
List<VideoInfoFilePost> addFileList = uploadFileList.stream()
.filter(item -> item.getFileId() == null)
.collect(Collectors.toList());
结果:
java
addFileList = [
VideoInfoFilePost(null, "u2", "p2"),
VideoInfoFilePost(null, "u3", "p3")
]
通过Stream API,我们简洁地实现了数据筛选和转换,代码更加清晰易读。