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

结语

希望对你有用~

原文地址:https://www.cnblogs.com/vcmq/p/12149654.html

时间: 2024-08-05 19:33:56

Java内存分页工具类的相关文章

分页 工具类 前后台代码 Java JavaScript (ajax) 实现 讲解

[博客园cnblogs笔者m-yb原创, 转载请加本文博客链接,笔者github: https://github.com/mayangbo666,公众号aandb7,QQ群927113708]https://www.cnblogs.com/m-yb/p/9986309.html分页功能的实现可以使用各种插件, 笔者今日闲来无事, 写了 分页工具类 前后台代码 Java JavaScript 的 实现及思路梳理.供大家参考.分页功能的需求一般有: 当前页/每页条数/总页数/总记录数/起始记录数/数

Java Web的分页工具类

最近写一个java web项目,以前分页的工具类,都是基础架构的人写好了的.也没有去细看,现在遇到这个状况. 就整理一下思路,自己写了一个分页的工具类.写的不好之处,还望斧正. 下面是我的代码: PageUtil.java 1 package util; 2 3 import java.util.Map; 4 5 /** 6 * 分页工具类 7 * @author lyh 8 * 9 */ 10 public class PageUtil { 11 private int total; //总数

个人常用工具类:分页工具类

import java.io.Serializable; import java.util.List; // 分页工具类 public class PageBean implements Serializable { private static final long serialVersionUID = -8741766802354222579L; private int pageSize = 5; // 每页显示多少条记录 private int currentPage = 1; //当前第

UrlUtils工具类,Java URL工具类,Java URL链接工具类

UrlUtils工具类,Java URL工具类,Java URL链接工具类 >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ?Copyright 蕃薯耀 2017年7月15日 http://www.cnblogs.com/fanshuyao/ Java代码   import java.util.Ha

Java 通过Xml导出Excel文件,Java Excel 导出工具类,Java导出Excel工具类

Java 通过Xml导出Excel文件,Java Excel 导出工具类,Java导出Excel工具类 ============================== ?Copyright 蕃薯耀 2017年9月13日 http://www.cnblogs.com/fanshuyao/ 直接上代码: import java.io.IOException; import java.lang.reflect.InvocationTargetException; import java.lang.ref

[精品] 收集的27个java开发常用工具类.基本满足开发需求

原文:[精品] 收集的27个java开发常用工具类.基本满足开发需求 源代码下载地址:http://www.zuidaima.com/share/1596028005993472.htm 最近从网上收集的java开发常用的工具类,分享给大家.基本满足开发需求.推荐给热爱最代码以及java的牛牛们.   每个类都有注释的,欢迎大家可以下载使用. 字符编码:CharTools, base64:Base64 *.java Md5加密:  MD5*.java 上传:*Uploader* 生成缩略图类:T

java MD5数据加密工具类

package com.wetuo.util; import java.security.MessageDigest; /**  * 数据加密工具类  * @author wzp  *  */ public class DataUtil { public static String md5(String str) { StringBuffer buffer = new StringBuffer(); char[] chars = { '0', '1', '2', '3', '4', '5', '

Java内存结构、类的初始化、及对象构造过程

概述 网上关于该题目的文章已经很多,我觉得把它们几个关联起来讲可能更好理解一下.与其它语言一样,它在执行我们写的程序前要先分配内存空间,以便于存放代码.数据:程序的执行过程其实依然是代码的执行及数据的读写过程:除了在执行我们写的显式的可见代码外,Jvm还会自动帮我们帮一些事,包括类的加载.初始化.GC等,这些也不特殊.以下分别来说下这些概念. Java内存结构.类的初始化.及对象构造过程

Java 敏感词过滤,Java 敏感词替换,Java 敏感词工具类

Java 敏感词过滤,Java 敏感词替换,Java 敏感词工具类   =========================== ?Copyright 蕃薯耀 2017年9月25日 http://www.cnblogs.com/fanshuyao/ 一.问题描述 很多对外网站的某些内容都需要过滤敏感词,避免政治与色@情上的问题. 二.解决方案 使用词库进行匹配过滤成 * (星号) Java 敏感词工具类及敏感词词库见附件. 1.下载后,有几个类,主要为WordFilter 这个工具类,使用方法如下