引入包:com.google.common.collect.RangeSet
主要方法有以下:
具体API进入code源码查询地址查看:http://grepcode.com/
区间段的统计,例如视频观看统计等计算,离散统计
使用注意事项:
1、RangeSet 、Set<Range> 空构造方法没外部暴露,所以Serializable序列化不了,这样如果使用kafaka发消息等网络传输则会丢失数据。需要使用自己定义业务Bean来达到传输功能。
例如kafaka发消息中,使用自己定义的Bean,记录开始、结束区间(相当于Range类),组成List进行替代。
private List<VideoProgressInfo> learnRanges ;
public class VideoProgressInfo {
/**
* 播放区间开始点,单位秒
*/
@Getter
@Setter
private long playRangeStart ;
/**
* 播放区间结束点,单位秒
*/
@Getter
@Setter
private long playRangeEnd ;
}
2、RangeSet 这个复杂类配置到Mongo Jpa类中进行存储,存储失败,Mongo不支持该RangeSet类,可以使用@Convert进行转化为MongoDB中使用的类(根据具体业务需要的数据)。我这边采用的是Set<Range>类替代,这样存储时没问题,查询时直接获得Set<Range> ,方便用于RangeSet类的方法。
Jpa中配置如下:
@Data
@Document(collection = "us")
public class UserPlayRecordEntity{
/**
* 该条记录用户观看视频上报记录集合,guava的RangeSet进行自动合并
* 采用TreeRangeSet
*/
@Field("lnrs")
private Set<Range> learnRangeSet ;
/**
* version 乐观锁
*/
@Field("ver")
@Version
private long version ;
}
3.RangeSet的一点应用方法
初始化RangeSet数据
RangeSet rangeSet = TreeRangeSet.create();
long learnSeconds =0 ;
for(VideoProgressInfo i:req.getPlayRanges()){
if(i.getPlayRangeEnd() >= i.getPlayRangeStart()){
rangeSet.add(Range.closed(i.getPlayRangeStart(), i.getPlayRangeEnd()));
learnSeconds = learnSeconds + i.getPlayRangeEnd() -i.getPlayRangeStart() ;
}
}
查询到的纪录数据,再增加新增的数据,set<Range> 到RangeSet的串联
RangeSet newRangeSet = TreeRangeSet.create();
Set<Range> oldRange = ulci.getLearnRangeSet() ;
if(oldRange !=null){
for(Range r:oldRange){
newRangeSet.add(r);
}
}
newRangeSet.addAll(addRangeSet);