天天看點

java PageUtil + stream 手動計算List 分頁

交代一下前言,資料是redis中查詢

java PageUtil + stream 手動計算List 分頁
140,193,88,117 格式大概是這樣。 需要切割為long類型的list數組。需要手動計算分頁,去mongodb中查詢資料。
      

這裡我用的手動計算分頁的是 hutool 工具包

import cn.hutool.core.util.PageUtil;  裡面挺多實用的工具      
<dependency>
    <groupId>cn.hutool</groupId>
    <artifactId>hutool-all</artifactId>
</dependency>      
int[] ints = PageUtil.transToStartEnd(page - 1, pageSize);      

傳入頁碼,和資料條數,計算資料起始位置

 将頁數和每頁條目數轉換為開始位置和結束位置 此方法用于包括結束位置的分頁方法 例如:

       頁碼:0,每頁10 =》 [0, 10]

       頁碼:1,每頁10 =》 [10, 20]

       ……

當setFirstPageNo(int)設定為1時:

       頁碼:1,每頁10 =》 [0, 10]

       頁碼:2,每頁10 =》 [10, 20]

       ……

Params:

pageNo – 頁碼(從0計數)

pageSize – 每頁條目數

Returns:

第一個數為開始位置,第二個數為結束位置

int[] ints = PageUtil.transToStartEnd(page - 1, pageSize);
           

通過工具傳回起始頁碼。

//根據起點, 和 終點, 截取到中間的vid 查詢
            List<Long> vids = split.stream().skip(ints[0]).limit(ints[1]).map(Long::valueOf).collect(Collectors.toList());
           

通過stream 流。搭配分頁工具。 實作手動分頁。 .map(Long::valueOf) 将string 轉為Long 類型

collect(Collectors.toList()); 收集到分頁之後的資料。如果起始位置超出list集合的size 不為報錯。結束位置超出list的size 不會出錯。 但是size為0 。 if (vids.size() > 0) { 判斷一下。進行下面的步驟。      

其實羅裡吧嗦一大堆,代碼就兩行。

//   将頁數和每頁條目數轉換為開始位置和結束位置 此方法用于包括結束位置的分頁方法 例如:   頁碼:0,每頁10 =》 [0, 10]
            int[] ints = PageUtil.transToStartEnd(page - 1, pageSize);
            //根據起點, 和 終點, 截取到中間的vid 查詢
            List<Long> vids = split.stream().skip(ints[0]).limit(ints[1]).map(Long::valueOf).collect(Collectors.toList());
           

 這裡放一下這個方法的全部代碼吧。

/**
     * 分頁查詢小視訊清單,按照時間倒序排序 優先查詢推薦的視訊,如果沒有推薦的視訊或已經查詢完成。再查詢預設的
     *
     * @param userId   使用者id
     * @param page     第幾頁
     * @param pageSize 每頁幾條
     * @return PageInfo<Video>
     */
    @Override
    public PageInfo<Video> queryVideoList(Long userId, Integer page, Integer pageSize) {
        //傳回的結果集
        PageInfo<Video> pageInfo = new PageInfo<>();
        pageInfo.setPageNum(page);
        pageInfo.setPageSize(pageSize);

        //小視訊推薦 redis key
        String redisKey = RedisKeyUtils.getVIDEOKEY(userId);
        //redis推薦視訊vid  140,193,88,117, vid
        String redisValue = redisTemplate.opsForValue().get(redisKey);

        //如果redis中推薦的視訊id不為空
        int recommendCount = 0;

            //如果redis 推薦視訊不為空
        if (StringUtils.isNotEmpty(redisValue)) {
            //分割key
            List<String> split = StrUtil.split(redisValue, ',');

            //用于查找預設視訊時,跳過的頁數計算
            recommendCount = split.size();

            //   将頁數和每頁條目數轉換為開始位置和結束位置 此方法用于包括結束位置的分頁方法 例如:   頁碼:0,每頁10 =》 [0, 10]
            int[] ints = PageUtil.transToStartEnd(page - 1, pageSize);
            //根據起點, 和 終點, 截取到中間的vid 查詢
            List<Long> vids = split.stream().skip(ints[0]).limit(ints[1]).map(Long::valueOf).collect(Collectors.toList());

            //如果推薦視訊vid 不為空,查詢推薦視訊
            if (vids.size() > 0) {
                Query query = Query.query(Criteria.where("vid").in(vids));
                List<Video> videos = mongoTemplate.find(query, Video.class);
                pageInfo.setRecords(videos);
                return pageInfo;
            }
        }

        //解決為了讓預設視訊從0開始,如果之前推薦視訊已經刷到第四頁。這裡需要減去4,包裝從0頁往下查詢
        int totalPage = PageUtil.totalPage(recommendCount, pageSize);
        //如果推薦視訊為空,或查詢完畢,查詢傳回預設的視訊清單
        PageRequest pageRequest = PageRequest.of(page - totalPage - 1, pageSize,
                Sort.by(Sort.Order.desc("created")));
        Query query = new Query();
        query.with(pageRequest);
        List<Video> videos = mongoTemplate.find(query, Video.class);
        pageInfo.setRecords(videos);
        return pageInfo;

    }