在项目中有一种常见数据封装需求,这里以产品的图片来说明。
返回给前端的数据格式可能长成这样
{
"data":{
"title":"我是产品的标题,请忽略我",
"images":["https://xxx.jpg","https://yyy.jpg"],
"video":"https://xxx.mp4"
}
}
但是你在数据库中拿到产品的资源信息的时候可能长成这样
[
{"type":1,"path":"https://xxx.jpg"},//图片1
{"type":1,"path":"https://yyy.jpg"},//图片2
{"type":2,"path":"https://xxx.mp4"}//视频
]
那么从上面的返回格式我们大概可以知道,只要我们能拿到Map<Integer,List<String>> 这种数据格式,然后get(type) 就可以拿到对应的图片和视频了。
//组装数据源
List<ProductResources> resourcesList = new ArrayList<>();
{
//图片1
ProductResources productResources = new ProductResources();
productResources.setPath("图片1路径");
productResources.setType(1);
resourcesList.add(productResources);
}
{
//图片2
ProductResources productResources = new ProductResources();
productResources.setPath("图片2路径");
productResources.setType(1);
resourcesList.add(productResources);
}
{
//视频1
ProductResources productResources = new ProductResources();
productResources.setPath("视频1路径");
productResources.setType(2);
resourcesList.add(productResources);
}
//遍历数据
if (CollectionUtils.isNotEmpty(resourcesList)) {
Map<Integer, List<ProductResources>> collect = resourcesList.stream().collect(Collectors.groupingBy(ProductResources::getType));
}
以上用groupingBy 好像根据type分组后,拿到的是Map<Integer, List<ProductResources>> 好像跟 Map<Integer,List<String>> 有一点差距。
一种方式就是将得到的Map<Integer, List<ProductResources>> 数据进行遍历 然后将ProductResources 里的path设置到List集合 最终拿到Map<Integer,List<String>>,但这不是最简洁的。
最简洁方式写法
Map<Integer, List<String>> collect = resourcesList.stream().collect(Collectors.groupingBy(ProductResources::getType, Collectors.mapping(ProductResources::getPath, Collectors.toList())));
一步到位,直接拿到目标 Map<Integer, List<String>> 数据格式。然后只要 collect.get(1) 拿到图片,collect.get(2)拿到视频即可。