Java內存分頁工具類


前言

工作過程中,經常會遇到基於內存數據進行分頁處理的情況,例如批量更新數據庫時,集合過大需要分批更新的情況,還有例如對緩存中的集合數據進行分頁獲取這種情況。
本文提供了通用的內存分頁工具,參考了網絡上的一些代碼,主要基於 subList() 方法實現,希望對你有所幫助!工具類源碼在本文底部。

本文原文鏈接地址:http://nullpointer.pw/Java%E5%86%85%E5%AD%98%E5%88%86%E9%A1%B5%E5%B7%A5%E5%85%B7%E7%B1%BB.html

優化前

首先來看一下正常如果要實現這些需求的話,代碼的實現是怎么樣的

// 分頁進行批量更新
private void batchUpdateStudent(List<Student> students) {
    int limit = 100;
    int size = students.size();
    int m = size / limit;
    int n = size % limit;
    for (int i = 1; i <= m; i++) {
        List<Student> list = students.subList((i - 1) * limit, i * limit);
        studentDao.batchUpdate(list);
    }
    if (n != 0) {
        List<Student> list = students.subList(m * limit, students.size());
        studentDao.batchUpdate(list);
    }
}

// 分頁獲取數據
public List<Student> pageStudents(Integer page, Integer pageSize) {
    if (page < 1) {
        page = 1;
    }

    int start = (page - 1) * pageSize;
    int limit = page * pageSize;

    // 從緩存中獲取全量數據
    List<Student> students = studentCache.getStudents();
    if (CollectionUtils.isEmpty(students)) {
        return new ArrayList<>();
    }
    if (limit > students.size()) {
        limit = students.size();
    }
    return students.subList(start, limit), students.size();
}

可以看出方法的代碼比較冗余,如果多處需要內存分頁,重復代碼不可避免會有很多!

優化后

// 分頁進行批量更新
private void batchUpdateStudent(List<Student> students) {
	RAMPager<Student> pager = new RAMPager<>(students, 100);
	// 方式一:使用迭代器
	Iterator<List<Student>> iterator = pager.iterator();
	while (iterator.hasNext()) {
		studentDao.batchUpdate(iterator.next());
	}

	// 方式二:使用索引
	//for (int i = 1; i <= pager.getPageCount(); i++) {
	//	studentDao.batchUpdate(pager.page(i));
	//}
}

// 分頁獲取數據
public List<Student> pageStudents(Integer page, Integer pageSize) {
	// 從緩存中獲取全量數據
	List<Student> students = studentCache.getStudents();
	RAMPager<Student> pager = new RAMPager<>(students, pageSize);
	return pager.page(page);
}

注:如果只是分頁,而不需要關注頁碼,使用迭代器即可;

工具類源碼

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;

/**
 * 類名稱:RAMPager
 * 類描述:內存分頁工具
 * 創建人:WeJan
 * 創建時間:2019年07月22日 13:43
 * Version: 1.1
 */
public class RAMPager<T> {
    private List<T> data;
    private int pageSize;

    /**
     * @param data     原始數據
     * @param pageSize 每頁條數
     */
    public RAMPager(List<T> data, int pageSize) {
        this.data = data;
        this.pageSize = pageSize;
    }

    /**
     * 獲取某頁數據,從第1頁開始
     *
     * @param pageNum 第幾頁
     * @return 分頁數據
     */
    public List<T> page(int pageNum) {
        if (pageNum < 1) {
            pageNum = 1;
        }
        int from = (pageNum - 1) * pageSize;
        int to = Math.min(pageNum * pageSize, data.size());
        if (from > to) {
            from = to;
        }
        return data.subList(from, to);
    }

    /**
     * 獲取總頁數
     */
    public int getPageCount() {
        if (pageSize == 0) {
            return 0;
        }
        return data.size() % pageSize == 0 ? (data.size() / pageSize) : (data.size() / pageSize + 1);
    }

    /**
     * 元素迭代器
     */
    public Iterator<List<T>> iterator() {
        return new Itr();
    }

    private class Itr implements Iterator<List<T>> {
        int page = 1;

        Itr() {
        }

        public boolean hasNext() {
            return page <= getPageCount();
        }

        public List<T> next() {
            int i = page;
            if (i > getPageCount())
                return new ArrayList<>();

            page = i + 1;
            return RAMPager.this.page(i);
        }
    }

    public static void main(String[] args) {
        List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8);
        System.out.println("原始數據是:" + list);

        int pageSize = 2;
        System.out.println("每頁大小是:" + pageSize);

        RAMPager<Integer> pager = new RAMPager<>(list, pageSize);
        System.out.println("總頁數是: " + pager.getPageCount());

        System.out.println("<- - - - - - - - - - - - - ->");

        // 無需感知頁碼情況下使用
        Iterator<List<Integer>> iterator = pager.iterator();
        while (iterator.hasNext()) {
            List<Integer> next = iterator.next();
            System.out.println("next: " + next);
        }

        System.out.println("<- - - - - - - - - - - - - ->");
        // 需要指定頁碼情況使用,頁碼從第一頁開始,且小於等於總頁數!
        for (int i = 1; i <= pager.getPageCount(); i++) {
            List<Integer> page = pager.page(i);
            System.out.println("第 " + i + " 頁數據是:" + page);
        }
    }
}

結語

希望對你有用~


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM