java - 有条件的重制清单
问题描述
有两个实体:
class GiftCertificate {
Long id;
List<Tag> tags;
}
class Tag {
Long id;
String name;
}
有一个清单
List<GiftCertificate>
例如,其中包含以下数据:
<1, [1, "Tag1"]>, <2, null>, <1, [2, "Tag2"]>
. (它不包含一组标签,但只有一个标签或根本没有它)。
我需要这样做,结果是这样的:
<1, {[1," Tag1 "], [2," Tag2 "]}>, <2, null>
。我的意思是,将第三个 GiftCertificate 中的标签添加到第一个对象的集合中,同时删除第三个。我想至少获得一些关于如何做到这一点的想法。使用流会很好。
解决方案
Java 9 引入flatMapping
了特别适合此类问题的收集器。将任务分为两个步骤。首先,构建一张礼券 ID 到标签列表的映射,然后组装一个新的GiftCertificate
对象列表:
import static java.util.stream.Collectors.flatMapping;
import static java.util.stream.Collectors.groupingBy;
import static java.util.stream.Collectors.toList;
......
Map<Long, List<Tag>> gcIdToTags = gcs.stream()
.collect(groupingBy(
GiftCertificate::getId,
flatMapping(
gc -> gc.getTags() == null ? Stream.empty() : gc.getTags().stream(),
toList()
)
));
List<GiftCertificate> r = gcIdToTags.entrySet().stream()
.map(e -> new GiftCertificate(e.getKey(), e.getValue()))
.collect(toList());
这假设GiftCertificate
有一个接受Long id
和List<Tag> tags
null
请注意,此代码通过创建一个空列表而不是在没有礼券 ID 的标签的情况下偏离您的要求。使用null
而不是空列表只是一个非常糟糕的设计,并迫使你null
到处检查来污染你的代码。
的第一个参数flatMapping
也可以写成 gc -> Stream.ofNullable(gc.getTags()).flatMap(List::stream)
你觉得它更具可读性。
推荐阅读
- xml - XSLT,将一些带有前缀的标签从 lt/gt 更改为 <>,而有些标签仍然带有 lt/gt
- java - 带有图像数据的 Java Volley 请求多部分表单
- java - 使用powershell修改部分JAVA_HOME文件夹路径
- html - 该页面在移动模式下显示屏幕外的隐藏项目
- java - 如何搜索 FTS3 表,以便搜索到的单词显示在列表顶部
- php - 找不到 php 命令,但 php70 正在工作
- observable - takeFirst 方法的替代方法是什么
- javascript - 在javascript中自动插入两个值的总和
- youtube-api - 偶尔会收到 YouTube iframe 播放器错误消息“发生错误。请稍后再试”
- node.js - 如何在 mongodb 中合并两个查询?