利⽤StreamAPI对List集合进⾏分组求和统计(2种⽅式)
⼀、根据String类型字段分组,求BigDecimal类型的和
1.原始数据及需求
需求:发货地和收货地相同的数据,合并这两项,并计算其他两项的数据之和
拿到的原始数据如下图所⽰:
2.利⽤StreamAPI处理List集合
代码如下:
@Override
public Map<String, Object> countCarLine(String begin, String end) {
// 线路统计
List<CarLineVO> carLineVOS = untCarLine(begin, end);
// 接收处理后的数据
List<CarLineVO> newCarLineVOs = new ArrayList<>();
// 数据分组统计处理
carLineVOS.parallelStream()
.upingBy(item -> (item .getDeliverAddress() + item .getCollectAddress()), List()))
.forEach((id, transfer) -> {
transfer.stream()
.reduce((a, b) -> new DeliverAddress(), a.getCollectAddress(), a.getCollectNetWeight().CollectNetWeight()), a.getTotalFreightPrice().TotalFreightPrice())))                            .ifPresent(newCarLineVOs::add);
});
Map<String, Object> map = new HashMap<>();
map.put("carLine", newCarLineVOs);
return map;
}
3.处理后得到符合需求的数据
处理后的数据:
4.实体类
CarLineVO类:
/**
* @Author: Ron
* @Create: 2020 10:14
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
public class CarLineVO {
private String deliverAddress;
private String collectAddress;
private BigDecimal collectNetWeight;
private BigDecimal totalFreightPrice;
}
实体类使⽤lombok插件
⼆、根据String类型字段分组,求int类型的和1.实体类
package del;
weight的几种形式import batisplus.annotation.IdType;
import batisplus.annotation.TableField;
import batisplus.annotation.TableId;
import batisplus.annotation.TableName;
import com.qs.del.BaseModel;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
perimental.Accessors;
/**
* 申请单和物料中间表
*
* @author Charles
* @since 2021/09/30
*/
@EqualsAndHashCode(callSuper = true)
@Data
@Accessors(chain = true)
@TableName("form_material")
@ApiModel(value="申请单和物料中间表", description="申请单和物料中间表")
public class FormMaterial extends BaseModel {
private static final long serialVersionUID = 1L;
/**
* 主键id
*/
@ApiModelProperty(value = "主键id")
@TableId(value = "id", type = IdType.ASSIGN_ID)
private String id;
/**
* 申请单id
*/
@ApiModelProperty(value = "申请单id")
private String applicationFormId;
/**
* 申请物料的id
*/
@ApiModelProperty(value = "申请物料的id")
private String materialId;
/**
* 申请物料的数量
*/
@ApiModelProperty(value = "申请物料的数量")
private int materialCount;
/**
* 取出的物料总数
*/
@ApiModelProperty(value = "取出的物料总数")
private int takeTotalCount;
/**
* 剩余物料数量
*/
@ApiModelProperty(value = "剩余物料数量")
private int remainingCount;
/**
* 此物料是否被领取完:0即未领取完,1即领取完
*/
@ApiModelProperty(value = "此物料是否被领取完")
private String materialFlag;
@TableField(exist = false)
private String materialNumber;
@TableField(exist = false)
private String materialName;
/**
* 传⼊的查询条件:物料数量
*/
@TableField(exist = false)
private String queryMaterialCount;
/**
* ⼊参
*/
public static final String APPLICATION_FORM_ID = "application_form_id";
public static final String MATERIAL_COUNT = "material_count";
}
2.需求
传过来的数据是这样的,物料id-materialId相同的话,物料数量求和materialCount [
{
"materialId": "1453637685838372866",
"materialCount": "15"
},
{
"materialId": "1453638065183809538",
"materialCount": "21"
},
{
"materialId": "1482879355628838914",
"materialCount": "8"
}
]
3.Stream处理
// 申请的重复物料信息,根据物料id,申请的物料数量求和合并成⼀条数据
/
/ formMaterialList就是来源的集合
List<FormMaterial> newList = new ArrayList<>();
formMaterialList.parallelStream()
.upingBy(FormMaterial::getMaterialId, List()))
.forEach(
(materialId, list) ->
list.stream()
.reduce(
(a, b) ->
new FormMaterial()
.MaterialId())
.
MaterialCount() + b.getMaterialCount()))
.ifPresent(newList::add));
三、总结
感觉和for循环差不多,流式运算⾥也是带了.forEach的⽅法了。