• 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);
            }
        }
    }
    

    结语

    希望对你有用~

  • 相关阅读:
    【LCA倍增】POJ1330-Nearest Common Ancestors
    【AC自动机/fail树】BZOJ3172- [Tjoi2013]单词
    【费用流】BZOJ1221-[HNOI2001] 软件开发
    【KM】POJ2195/HDU1533-Going home
    【KM算法】HDU2255-奔小康赚大钱
    【匈牙利算法】BZOJ1059-[ZJOI2007]矩阵游戏
    【KMP】BZOJ3670-[Noi2014]动物园
    【Treap】BZOJ1588-[HNOI2002]营业额统计
    【Treap模板详细注释】BZOJ3224-普通平衡树
    【tarjan求割顶】BZOJ2730-[HNOI2012]矿场搭建
  • 原文地址:https://www.cnblogs.com/vcmq/p/12149654.html
Copyright © 2020-2023  润新知