1.使用场景
比如评论系统中,我们有多项打分,我们要同时对多个评分项求平均值,这个在数据库可以直接通过SQL也可以解决,在java 8后提供的Stream API也能解决这种求值问题,不适合数据量太大的统计。
2.数据对象
/**
* 用户评分实体
*/
public class UserCommentDTO implements Serializable {
/**
* 详细评价1(如:服务)
*/
private Integer detailScore1;
/**
* 详细评价2(如:体验)
*/
private Integer detailScore2;
/**
* 详细评价3(如:便捷)
*/
private Integer detailScore3;
/**
* 详细评价4(如:性价比)
*/
private Integer detailScore4;
}
/**
* 计算实体
*/
public class CommentScoreVO implements Serializable {
/**
* 合计1
*/
private Integer sum1 = 0;
/**
* 平均数1
*/
private BigDecimal avg1;
/**
* 总数
*/
private Integer count1 = 0;
/**
* 合计2
*/
private Integer sum2 = 0;
/**
* 平均数2
*/
private BigDecimal avg2;
/**
* 总数2
*/
private Integer count2 = 0;
/**
* 合计3
*/
private Integer sum3 = 0;
/**
* 平均数3
*/
private BigDecimal avg3;
/**
* 总数3
*/
private Integer count3 = 0;
/**
* 合计4
*/
private Integer sum4 = 0;
/**
* 平均数4
*/
private BigDecimal avg4;
/**
* 总数4
*/
private Integer count4 = 0;
public CommentScoreVO(UserCommentDTO userCommentDTO) {
this.sum1 = userCommentDTO.getDetailScore1() == null ? 0 : userCommentDTO.getDetailScore1();
this.sum2 = userCommentDTO.getDetailScore2() == null ? 0 : userCommentDTO.getDetailScore2();
this.sum3 = userCommentDTO.getDetailScore3() == null ? 0 : userCommentDTO.getDetailScore3();
this.sum4 = userCommentDTO.getDetailScore4() == null ? 0 : userCommentDTO.getDetailScore4();
this.count1 = userCommentDTO.getDetailScore1() == null ? 0 : 1;
this.count2 = userCommentDTO.getDetailScore2() == null ? 0 : 1;
this.count3 = userCommentDTO.getDetailScore3() == null ? 0 : 1;
this.count4 = userCommentDTO.getDetailScore4() == null ? 0 : 1;
}
public CommentScoreVO() {
}
public CommentScoreVO add(CommentScoreVO commentScoreVO) {
this.sum1 += commentScoreVO.getSum1();
this.sum2 += commentScoreVO.getSum2();
this.sum3 += commentScoreVO.getSum3();
this.sum4 += commentScoreVO.getSum4();
this.count1 += commentScoreVO.getCount1();
this.count2 += commentScoreVO.getCount2();
this.count3 += commentScoreVO.getCount3();
this.count4 += commentScoreVO.getCount4();
return this;
}
public BigDecimal getAvg1() {
return new BigDecimal(sum1).divide(new BigDecimal(count1), 1, RoundingMode.HALF_UP);
}
public BigDecimal getAvg2() {
return new BigDecimal(sum2).divide(new BigDecimal(count2), 1, RoundingMode.HALF_UP);
}
public BigDecimal getAvg3() {
return new BigDecimal(sum3).divide(new BigDecimal(count3), 1, RoundingMode.HALF_UP);
}
public BigDecimal getAvg4() {
return new BigDecimal(sum4).divide(new BigDecimal(count4), 1, RoundingMode.HALF_UP);
}
public BigDecimal getEntireAvg() {
return new BigDecimal(this.sum1 + this.sum2 + this.sum3 + this.sum4)
.divide(new BigDecimal(this.count1 + this.count2 + this.count3 + this.count4), 1, RoundingMode.HALF_UP);
}
}
3.代码实现
CommentScoreVO commentScore = userComments.stream().map(CommentScoreVO::new)
.reduce(new CommentScoreVO(), CommentScoreVO::add);
就是这么不可思议,用Stream API可以写出相当多的简洁代码。