一、根據String類型字段分組,求BigDecimal類型的和
1.原始數據及需求
需求:發貨地和收貨地相同的數據,合並這兩項,並計算其他兩項的數據之和
拿到的原始數據如下圖所示:
2.利用StreamAPI處理List集合
代碼如下:
@Override
public Map<String, Object> countCarLine(String begin, String end) {
// 線路統計
List<CarLineVO> carLineVOS = dashboardMapper.countCarLine(begin, end);
// 接收處理后的數據
List<CarLineVO> newCarLineVOs = new ArrayList<>();
// 數據分組統計處理
carLineVOS.parallelStream()
.collect(Collectors.groupingBy(item -> (item .getDeliverAddress() + item .getCollectAddress()), Collectors.toList()))
.forEach((id, transfer) -> {
transfer.stream()
.reduce((a, b) -> new CarLineVO(a.getDeliverAddress(), a.getCollectAddress(), a.getCollectNetWeight().add(b.getCollectNetWeight()), a.getTotalFreightPrice().add(b.getTotalFreightPrice())))
.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 com.qs.modules.formMaterial.model;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.qs.db.base.model.BaseModel;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.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()
.collect(Collectors.groupingBy(FormMaterial::getMaterialId, Collectors.toList()))
.forEach(
(materialId, list) ->
list.stream()
.reduce(
(a, b) ->
new FormMaterial()
.setMaterialId(a.getMaterialId())
.setMaterialCount(a.getMaterialCount() + b.getMaterialCount()))
.ifPresent(newList::add));
三、總結
感覺和for循環差不多,流式運算里也是帶了.forEach
的方法了。