本文共 1704 字,大约阅读时间需要 5 分钟。
引入包:com.google.common.collect.RangeSet
主要方法有以下:
具体API进入code源码查询地址查看:
区间段的统计,例如视频观看统计等计算,离散统计
使用注意事项:
1、RangeSet 、Set<Range> 空构造方法没外部暴露,所以Serializable序列化不了,这样如果使用kafaka发消息等网络传输则会丢失数据。需要使用自己定义业务Bean来达到传输功能。
例如kafaka发消息中,使用自己定义的Bean,记录开始、结束区间(相当于Range类),组成List进行替代。
private ListlearnRanges ;
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 Set3.RangeSet的一点应用方法learnRangeSet ; /** * version 乐观锁 */ @Field("ver") @Version private long version ;}
初始化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(); SetoldRange = ulci.getLearnRangeSet() ; if(oldRange !=null){ for(Range r:oldRange){ newRangeSet.add(r); } } newRangeSet.addAll(addRangeSet);