本文最后更新于:2021年6月15日 晚上
前言 工作过程中,经常会遇到基于内存数据进行分页处理的情况,例如批量更新数据库时,集合过大需要分批更新的情况,还有例如对缓存中的集合数据进行分页获取这种情况。 本文提供了通用的内存分页工具,参考了网络上的一些代码,主要基于 subList() 方法实现,希望对你有所帮助!工具类源码在本文底部。
优化前 首先来看一下正常如果要实现这些需求的话,代码的实现是怎么样的
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 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(); }
可以看出方法的代码比较冗余,如果多处需要内存分页,重复代码不可避免会有很多!
优化后 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 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()); } }public List<Student> pageStudents (Integer page, Integer pageSize) { List<Student> students = studentCache.getStudents(); RAMPager<Student> pager = new RAMPager<>(students, pageSize); return pager.page(page); }
注:如果只是分页,而不需要关注页码,使用迭代器即可;
工具类源码 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 import java.util.ArrayList;import java.util.Arrays;import java.util.Iterator;import java.util.List;public class RAMPager <T > { private List<T> data; private int pageSize; public RAMPager (List<T> data, int pageSize) { this .data = data; this .pageSize = pageSize; } 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); } } }
结语 希望对你有用~