1. 程式人生 > >區間統計類guava中RangeSet使用以及注意

區間統計類guava中RangeSet使用以及注意

引入包: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中配置如下:

@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);