Collectors是stream流处理最后一个环节collect的工具类,主要用于最后对汇集数据的处理,如将流处理结果存储为某种集合类型以及对结果进行分组、筛选、计算等操作.其主要功能如下:
本节内容还是以中奖记录对象来例:
/**
* 中奖记录
* @author shixinke
* @date 2019-1-25
*/
class AwardRecord {
/**
* 记录ID
*/
private Long recordId;
/**
* 中奖用户ID
*/
private Long userId;
/**
* 数量
*/
private Integer num;
/**
* 中奖物品ID
*/
private Long itemId;
/**
* 中奖物品的单个价值
*/
private Double worth;
public Long getRecordId() {
return recordId;
}
public void setRecordId(Long recordId) {
this.recordId = recordId;
}
public Long getUserId() {
return userId;
}
public void setUserId(Long userId) {
this.userId = userId;
}
public Integer getNum() {
return num;
}
public void setNum(Integer num) {
this.num = num;
}
public Long getItemId() {
return itemId;
}
public void setItemId(Long itemId) {
this.itemId = itemId;
}
public Double getWorth() {
return worth;
}
public void setWorth(Double worth) {
this.worth = worth;
}
public AwardRecord(Long recordId, Long userId, Integer num, Long itemId, Double worth) {
this.recordId = recordId;
this.userId = userId;
this.num = num;
this.itemId = itemId;
this.worth = worth;
}
@Override
public String toString() {
return "AwardRecord{" +
"recordId=" + recordId +
", userId=" + userId +
", num=" + num +
", itemId=" + itemId +
", worth=" + worth +
'}';
}
}
public class CollectorDemo {
public static void main(String[] args) {
List<AwardRecord> awardRecordList = new ArrayList<AwardRecord>(5);
awardRecordList.add(new AwardRecord(300001L, 5000001L, 1, 8754578L, 1.35));
awardRecordList.add(new AwardRecord(300002L, 5200001L, 2, 8754579L, 2.35));
awardRecordList.add(new AwardRecord(300003L, 5000001L, 1, 8754878L, 0.35));
awardRecordList.add(new AwardRecord(300004L, 5300001L, 3, 8354578L, 0.21));
awardRecordList.add(new AwardRecord(300005L, 5200001L, 1, 8154578L, 2.63));
}
}
一、将流汇集成集合对象
- toList : 输出为List对象
- toMap : 输出为Map对象
- toSet : 输出为Set对象
- toCollection : 输出为集合对象
- toConcurrentMap : 输出为ConcurrentMap对象
List<AwardRecord> awardRecordList = new ArrayList<AwardRecord>(10);
//省略其他流操作
awardRecordList.stream().collect(Collectors.toList());
二、分组
- groupingBy : 按照某个分组函数进行分组
- groupingByConcurrent : 按照某个分组函数进行分组(并发版,即线程安全版)
/**
* 1.分组(通过userId分组,获取按用户分组的用户的获奖列表)
*/
Map<Long, List<AwardRecord>> awardRecordMap = awardRecordList.stream().collect(Collectors.groupingBy(AwardRecord::getUserId));
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对象
/**
* 对结果进行组合并形成新的集合(中奖用户列表)
*/
List<Long> awardUserList = awardRecordList.stream().collect(Collectors.mapping(c->c.getUserId(), Collectors.toList()));
System.out.println(awardRecordList);
四、计算
1.最大值 maxBy
- 参数为一个Comparator对象
/**
* 计算中奖价值最多的记录
*/
Optional<AwardRecord> maxRecord = awardRecordList.stream().collect(
Collectors.maxBy(
(AwardRecord c1, AwardRecord c2)->Double.valueOf(c1.getNum()*c1.getWorth()).compareTo(
Double.valueOf(c2.getNum()*c2.getWorth()))));
System.out.println(maxRecord.get()); //AwardRecord{recordId=300002, userId=5200001, num=2, itemId=8754579, worth=2.35}
2.最小值 minBy
- 参数为一个Comparator对象
/**
* 计算中奖价值最小的记录
*/
Optional<AwardRecord> minRecord = awardRecordList.stream().collect(
Collectors.minBy(
(AwardRecord c1, AwardRecord c2)->Double.valueOf(c1.getNum()*c1.getWorth()).compareTo(
Double.valueOf(c2.getNum()*c2.getWorth()))));
System.out.println(minRecord.get()); //AwardRecord{recordId=300003, userId=5000001, num=1, itemId=8754878, worth=0.35}
3.总和
- summingInt : 计算元素为int型的总和
- summingLong : 计算元素为Long型的总和
- summingDouble : 计算元素为Double型的总和
/**
* 计算总数量
*/
System.out.println(awardRecordList.stream().collect(Collectors.summingInt(c -> c.getNum()))); //8
System.out.println(awardRecordList.stream().collect(Collectors.summingDouble(c -> c.getNum() * c.getWorth()))); //9.66
4.平均值
- averagingInt
- averagingLong
- averagingDouble
/**
* 平均中奖个数
*/
System.out.println(awardRecordList.stream().collect(Collectors.averagingInt(c -> c.getNum()))); //1.6
/**
* 平均中奖金额
*/
System.out.println(awardRecordList.stream().collect(Collectors.averagingDouble(c -> c.getWorth()))); //1.3780000000000001
5.个数 counting
/**
* 统计中奖人数
*/
System.out.println(awardRecordList.stream().map(AwardRecord::getUserId).distinct().collect(Collectors.counting())); //3
6.计算上面所有的
- summarizingInt
- summarizingLong
- summarizingDouble
/**
* 所有统计指标汇总
*/
System.out.println(awardRecordList.stream().collect(Collectors.summarizingInt(c -> c.getNum()))); //IntSummaryStatistics{count=5, sum=8, min=1, average=1.600000, max=3}