Java8新特性(5).Stream流处理收集器Collectors工具类

Collectors是stream流处理最后一个环节collect的工具类,主要用于最后对汇集数据的处理,如将流处理结果存储为某种集合类型以及对结果进行分组、筛选、计算等操作.其主要功能如下:

本节内容还是以中奖记录对象来例:

  1. /**
  2. * 中奖记录
  3. * @author shixinke
  4. * @date 2019-1-25
  5. */
  6. class AwardRecord {
  7. /**
  8. * 记录ID
  9. */
  10. private Long recordId;
  11. /**
  12. * 中奖用户ID
  13. */
  14. private Long userId;
  15. /**
  16. * 数量
  17. */
  18. private Integer num;
  19. /**
  20. * 中奖物品ID
  21. */
  22. private Long itemId;
  23. /**
  24. * 中奖物品的单个价值
  25. */
  26. private Double worth;
  27. public Long getRecordId() {
  28. return recordId;
  29. }
  30. public void setRecordId(Long recordId) {
  31. this.recordId = recordId;
  32. }
  33. public Long getUserId() {
  34. return userId;
  35. }
  36. public void setUserId(Long userId) {
  37. this.userId = userId;
  38. }
  39. public Integer getNum() {
  40. return num;
  41. }
  42. public void setNum(Integer num) {
  43. this.num = num;
  44. }
  45. public Long getItemId() {
  46. return itemId;
  47. }
  48. public void setItemId(Long itemId) {
  49. this.itemId = itemId;
  50. }
  51. public Double getWorth() {
  52. return worth;
  53. }
  54. public void setWorth(Double worth) {
  55. this.worth = worth;
  56. }
  57. public AwardRecord(Long recordId, Long userId, Integer num, Long itemId, Double worth) {
  58. this.recordId = recordId;
  59. this.userId = userId;
  60. this.num = num;
  61. this.itemId = itemId;
  62. this.worth = worth;
  63. }
  64. @Override
  65. public String toString() {
  66. return "AwardRecord{" +
  67. "recordId=" + recordId +
  68. ", userId=" + userId +
  69. ", num=" + num +
  70. ", itemId=" + itemId +
  71. ", worth=" + worth +
  72. '}';
  73. }
  74. }
  75. public class CollectorDemo {
  76. public static void main(String[] args) {
  77. List<AwardRecord> awardRecordList = new ArrayList<AwardRecord>(5);
  78. awardRecordList.add(new AwardRecord(300001L, 5000001L, 1, 8754578L, 1.35));
  79. awardRecordList.add(new AwardRecord(300002L, 5200001L, 2, 8754579L, 2.35));
  80. awardRecordList.add(new AwardRecord(300003L, 5000001L, 1, 8754878L, 0.35));
  81. awardRecordList.add(new AwardRecord(300004L, 5300001L, 3, 8354578L, 0.21));
  82. awardRecordList.add(new AwardRecord(300005L, 5200001L, 1, 8154578L, 2.63));
  83. }
  84. }

一、将流汇集成集合对象

  • toList : 输出为List对象
  • toMap : 输出为Map对象
  • toSet : 输出为Set对象
  • toCollection : 输出为集合对象
  • toConcurrentMap : 输出为ConcurrentMap对象
  1. List<AwardRecord> awardRecordList = new ArrayList<AwardRecord>(10);
  2. //省略其他流操作
  3. awardRecordList.stream().collect(Collectors.toList());

二、分组

  • groupingBy : 按照某个分组函数进行分组
  • groupingByConcurrent : 按照某个分组函数进行分组(并发版,即线程安全版)
  1. /**
  2. * 1.分组(通过userId分组,获取按用户分组的用户的获奖列表)
  3. */
  4. Map<Long, List<AwardRecord>> awardRecordMap = awardRecordList.stream().collect(Collectors.groupingBy(AwardRecord::getUserId));
  5. System.out.println(awardRecordMap); //{5300001=[AwardRecord{recordId=300004, userId=5300001, num=3, itemId=8354578, worth=0.21}], 5000001=[AwardRecord{recordId=300001, userId=5000001, num=1, itemId=8754578, worth=1.35}, AwardRecord{recordId=300003, userId=5000001, num=1, itemId=8754878, worth=0.35}], 5200001=[AwardRecord{recordId=300002, userId=5200001, num=2, itemId=8754579, worth=2.35}, AwardRecord{recordId=300005, userId=5200001, num=1, itemId=8154578, worth=2.63}]}

三、筛选

  • mapping
    • 第一个参数为组合的函数式接口
    • 第二个参数为Collector对象
  1. /**
  2. * 对结果进行组合并形成新的集合(中奖用户列表)
  3. */
  4. List<Long> awardUserList = awardRecordList.stream().collect(Collectors.mapping(c->c.getUserId(), Collectors.toList()));
  5. System.out.println(awardRecordList);

四、计算

1.最大值 maxBy
  • 参数为一个Comparator对象
  1. /**
  2. * 计算中奖价值最多的记录
  3. */
  4. Optional<AwardRecord> maxRecord = awardRecordList.stream().collect(
  5. Collectors.maxBy(
  6. (AwardRecord c1, AwardRecord c2)->Double.valueOf(c1.getNum()*c1.getWorth()).compareTo(
  7. Double.valueOf(c2.getNum()*c2.getWorth()))));
  8. System.out.println(maxRecord.get()); //AwardRecord{recordId=300002, userId=5200001, num=2, itemId=8754579, worth=2.35}
2.最小值 minBy
  • 参数为一个Comparator对象
  1. /**
  2. * 计算中奖价值最小的记录
  3. */
  4. Optional<AwardRecord> minRecord = awardRecordList.stream().collect(
  5. Collectors.minBy(
  6. (AwardRecord c1, AwardRecord c2)->Double.valueOf(c1.getNum()*c1.getWorth()).compareTo(
  7. Double.valueOf(c2.getNum()*c2.getWorth()))));
  8. System.out.println(minRecord.get()); //AwardRecord{recordId=300003, userId=5000001, num=1, itemId=8754878, worth=0.35}
3.总和
  • summingInt : 计算元素为int型的总和
  • summingLong : 计算元素为Long型的总和
  • summingDouble : 计算元素为Double型的总和
  1. /**
  2. * 计算总数量
  3. */
  4. System.out.println(awardRecordList.stream().collect(Collectors.summingInt(c -> c.getNum()))); //8
  5. System.out.println(awardRecordList.stream().collect(Collectors.summingDouble(c -> c.getNum() * c.getWorth()))); //9.66
4.平均值
  • averagingInt
  • averagingLong
  • averagingDouble
  1. /**
  2. * 平均中奖个数
  3. */
  4. System.out.println(awardRecordList.stream().collect(Collectors.averagingInt(c -> c.getNum()))); //1.6
  5. /**
  6. * 平均中奖金额
  7. */
  8. System.out.println(awardRecordList.stream().collect(Collectors.averagingDouble(c -> c.getWorth()))); //1.3780000000000001
5.个数 counting
  1. /**
  2. * 统计中奖人数
  3. */
  4. System.out.println(awardRecordList.stream().map(AwardRecord::getUserId).distinct().collect(Collectors.counting())); //3
6.计算上面所有的
  • summarizingInt
  • summarizingLong
  • summarizingDouble
  1. /**
  2. * 所有统计指标汇总
  3. */
  4. System.out.println(awardRecordList.stream().collect(Collectors.summarizingInt(c -> c.getNum()))); //IntSummaryStatistics{count=5, sum=8, min=1, average=1.600000, max=3}