java小技能:对list集合根据条件进行分组、过滤和字段筛选
引言
需求背景:查询机构下的代理商费率信息,查询结果对分润和返利进行分组。
实现思路:使用jdk8的流式编程对list集合进行分组
I 对list根据条件进行分组
1.1 费率信息实体
OrganPayRate
@ApiModelProperty(value = "类型(FR:分润,FL:返利)")
@TableField("type")
private EFacilitatorOrganPayRateType type;
@ApiModelProperty(value = "基础费率")
@TableField("base_rate")
private BigDecimal baseRate;
@ApiModelProperty(value = "附加费率")
@TableField("extra_rate")
private BigDecimal extraRate;
@ApiModelProperty(value = "优惠费率")
@TableField("discount_rate")
private BigDecimal discountRate;
@ApiModelProperty(value = "封顶手续费")
@TableField("capping_fee")
private BigDecimal cappingFee;
@ApiModelProperty(value = "状态(1:启用,0停用)")
@TableField("state")
private EEnableState state;
@ApiModelProperty(value = "支付方式")
@TableField("pay_way_id")
private EMerchantPayRateType payWayId;
@ApiModelProperty(value = "结算周期(T1,D1,D0,R0)")
@TableField("settlement_cycle")
private ESettlementCycle settlementCycle;
1.2 dto
public class OrganPayRateDto {
@ApiModelProperty(value = "分润费率信息")
private List<OrganPayRate> fenrunPayRates;
@ApiModelProperty(value = "返利比例信息")
private List<OrganPayRate> fanliPayRates;
1.3 查询数据
使用jdk8的流式编程对list集合进行分组
List<OrganPayRate> organPayRates = tFacFacilitatorOrganPayRateService.list(lambda);
//organPayRates 根据EFacilitatorOrganPayRateType进行分组。
//使用jdk8的流式编程对list集合进行分组
Map<EFacilitatorOrganPayRateType, List<OrganPayRate>> listMap = organPayRates.stream().collect(Collectors.groupingBy(t -> t.getType()));
OrganPayRateDto dto = new OrganPayRateDto();
dto.setFanliPayRates(listMap.get(EFacilitatorOrganPayRateType.FL));
dto.setFenrunPayRates(listMap.get(EFacilitatorOrganPayRateType.FR));
"data": {
"fenrunPayRates": [
"type": "FR",
"typeText": "分润",
"payWayId": "3",
"payWayIdText": "借记卡",
"settlementCycle": "D0",
"settlementCycleText": "D0",
"baseRate": "0.00",
"extraRate": "0.00",
"discountRate": "0.00",
"cappingFee": "0.00",
"state": "1",
"stateText": "启用"
"type": "FR",
"typeText": "分润",
"payWayId": "4",
"payWayIdText": "贷记卡",
"settlementCycle": "D0",
"settlementCycleText": "D0",
"baseRate": "0.00",
"extraRate": "0.00",
"discountRate": "0.00",
"cappingFee": "0.00",
"state": "1",
"stateText": "启用"
"fanliPayRates": [
"type": "FL",
"typeText": "返利",
"payWayId": "3",
"payWayIdText": "借记卡",
"settlementCycle": "D0",
"settlementCycleText": "D0",
"baseRate": "0.00",
"extraRate": "0.00",
"discountRate": "0.00",
"cappingFee": "0.00",
"state": "1",
"stateText": "启用"
"typeText": "返利",
"payWayId": "4",
"payWayIdText": "贷记卡",
"settlementCycle": "D0",
"settlementCycleText": "D0",
"baseRate": "0.00",
"extraRate": "0.00",
"discountRate": "0.00",
"cappingFee": "0.00",
"state": "1",
"stateText": "启用"
II 对list根据条件进行过滤和字段筛选
需求:修改代理商角色权限时,判断是否存在权限被移除,如果存在,则穿透删除所有下级代理商相对应的权限值。
1.1 代理商配置角色权限步骤
- 比对得出要移除的权限
- 取出用户角色关系表数据,判断是否有直属下级代理商使用了被编辑的角色。
- 穿透删除所有下级代理商相对应的权限值
1.2 实体
角色实体
@ApiModelProperty(value = "主键id")
@TableId("id")
private Long id;
@ApiModelProperty(value = "角色名称")
@TableField("name")
private String name;
@ApiModelProperty(value = "代理商")
@TableField("facilitator_id")
private Long facilitatorId;
角色权限实体
@ApiModelProperty(value = "主键id")
@TableId("id")
private Long id;
@ApiModelProperty(value = "菜单编码对应系统菜单的code")
@TableField("menu_code")
private Integer menuCode;
1.3 穿透删除所有下级代理商相对应的权限值
先查询满足条件的权限,再进行批量删除。避免频繁连接数据库。
/*
* 1:比对得出要移除的权限
2:取出用户角色关系表数据,判断是否有直属下级代理商使用了被编辑的角色。
3:穿透删除所有下级代理商相对应的权限值
private void batchPenetrationDeletionpermissions(RoleAllocationPermissionsDto input,TFacFacilitatorRole role) {
//1. 查询原来的角色权限
LambdaQueryWrapper<RolePermission> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(RolePermission::getFacilitatorRoleId, input.getId());
queryWrapper.select(RolePermission::getMenuCode);
List<RolePermission> oldList = tFacFacilitatorRolePermissionService.list(queryWrapper);
List<Integer> oldCodeList = oldList.stream().map(RolePermission::getMenuCode).collect(Collectors.toList());
List<Integer> newCodeList = input.getPermissionIds();
List<Integer> deleteCodeList = oldCodeList.stream().filter(s -> {
return !newCodeList.contains(s);
}).collect(Collectors.toList());
//2. 取出用户角色关系表数据,判断是否有直属下级代理商使用了被编辑的角色。
List<Long> fids = getUserByRoleId(input.getId());
if (fids.size() < 1) {//角色没有代理商使用
return;
if (fids.size() == 1 && fids.contains(role.getFacilitatorId())) {//当前角色只有本级代理商使用
return;
//3. 当前角色被直属下级使用,穿透删除所有下级代理商相对应的权限值。
// 穿透查询下级代理商
List<Long> childFacids= getChildFacByRoleId(role.getFacilitatorId());
// 排除掉本级
childFacids.remove(role.getFacilitatorId());
// 封装要删除的权限
List<Long> permissionIds = new ArrayList<>();
childFacids.forEach(s->{
// 3.1. 根据代理商ID查询角色
List<Long> rids = getRoleIdByfacId(s);
// 3.2. 根据角色ID查询权限code,判断是否包含被删除的权限。
rids.forEach(item->{
List<Long> pids=getPermissionIdByRoleId(item,deleteCodeList);
if(pids.size()>0){
permissionIds.addAll(pids);