區間統計類guava中RangeSet使用以及注意
阿新 • • 發佈:2019-02-17
引入包:com.google.common.collect.RangeSet
主要方法有以下:
區間段的統計,例如視訊觀看統計等計算,離散統計
使用注意事項:
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中配置如下:
3.RangeSet的一點應用方法@Data @Document(collection = "us") public class UserPlayRecordEntity{ /** * 該條記錄使用者觀看視訊上報記錄集合,guava的RangeSet進行自動合併 * 採用TreeRangeSet */ @Field("lnrs") private Set<Range> 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();
Set<Range> oldRange = ulci.getLearnRangeSet() ;
if(oldRange !=null){
for(Range r:oldRange){
newRangeSet.add(r);
}
}
newRangeSet.addAll(addRangeSet);