需求
有一个订单工作站OrderWorkstationPO集合,我们需要从这个集合中,得到一个关于工作站进行分组,并且组内只包含播种墙的Map集合
分析
按照非lambda方式实现,需要新建一个Map<Integer,List>集合。遍历list集合,获取集合中每一个实体的工作站id,并比较map中的key,相同key进行存放每一个播种墙id。
如果采用lambda方式,我们也需要遍历集合,稍微不同的是,我们是通过stream的方式操作集合,并且要考虑工作站id和播种墙id不能为空的情况,因为我们后续还需要对流进行操作。
实现
订单工作站实体:
// 订单工作站关系
@Data
public class OrderWorkstationPO {
// 播种位id
private Integer seedingAreaId;
// 工作站id
private Integer workstationId;
// 播种墙id
private Integer seedingWallId;
}
非Lambda表达式使用方式:
Map<Integer, List<Integer>> result = new HashMap<>();
for (OrderWorkstationPO orderPO : list) {
if (result.containsKey(orderPO.getWorkstationId())) {
List<Integer> vals = result.get(orderPO.getWorkstationId());
if (vals == null) vals = new ArrayList<>();
Set<Integer> unique = new HashSet<>(vals);
if (orderPO.getSeedingWallId() == null) continue;
unique.add(orderPO.getSeedingWallId());
result.put(orderPO.getWorkstationId(), new ArrayList<>(unique));
continue;
}
if (orderPO.getWorkstationId() == null
|| orderPO.getSeedingWallId() == null) continue;
List<Integer> list = new ArrayList<>();
list.add(orderPO.getSeedingWallId());
result.put(orderPO.getWorkstationId(), list);
}
Lambda使用方式:
Map<Integer, List<Integer>> result = list.stream()
.filter(entity -> entity.getWorkstationId() != null && entity.getSeedingWallId() != null)
.collect(Collectors.collectingAndThen(
Collectors.groupingBy(OrderWorkstationPO::getWorkstationId),
// 这一段可以再简化,见下文
entry -> entry.entrySet().stream().collect(
Collectors.toMap(
Map.Entry::getKey,
entrySub -> entrySub.getValue()
.stream()
.map(OrderWorkstationPO::getSeedingAreaId)
.collect(Collectors.toList())
)
)
));
Lambda简洁用法:
Map<Integer, List<Integer>> result = list.stream()
.filter(entity -> entity.getWorkstationId() != null && entity.getSeedingWallId() != null)
.collect(
Collectors.groupingBy(
OrderWorkstationPO::getWorkstationId),
Collectors.mapping(OrderWorkstationPO::getSeedingAreaId,Collectors.toList()));
Lambda使用技巧总结
- 考虑非Lambda情况下怎么实现
- 对集合进行流处理stream
- Collectors.collectingAndThen这个流处理功能很强大,第二个参数是对第一个参数形成的新流进行处理。