一个对List中的数据进行分页的工具类
2017-12-02 15:49
375 查看
在项目当中,使用分页方式分批次查询数据并渲染到页面是一种相当普遍的做法。目的是避免浏览器一次性加载过多的数据导致的页面迟缓或者崩溃。另外,在数据总量过大的情况下,一次性将内容都查询出来,查询出来的结果最初是放在内存里面的,内存也没有这么大,因此很容易导致内存不够或宕机。
往往,项目中还存在另外一种分页方式,也即内存分页。内存分页的数据总量往往是已经全部加载到内存中了的。因此可以想到,内存分页场景中的需要进行分页的数据对象并不大。 那么问题就来了?我们为什么还要进行分页,是不是画蛇添足多此一举了? 事实上有没有必要进行内存分页得具体问题具体分析。笔者在写此文之前,就已经总结出两种不得不使用内存分页机制的场景:
场景(1): 数据总量虽然不大,不足以对内存或性能造成威胁,但在使用数据进行计算的过程中产生的中间数据或最终结果总量巨大,计算产生的大量临时数据或最终结果才是可能导致性能问题的关键原因。这种情况下我们也只能将总数据划分成多个更小的批次进行处理,每次只处理一个批次,这样可以使每一个小批次产生的临时数据或计算结果不足以威胁到整个计算过程。当一个批次处理结束,临时数据被销毁之后,再进行下一批次的处理。
场景(2):一次性处理数据的耗时大于处理每一个小的批次数据的耗时:比如需要将这批数据作为参数调用某个接口,数据量大,接口提供方处理速度迟缓导致的超时无法获取数据。这种情况下,分批分多次调用接口成功的概率大于一个批次单次调用接口的概率。
场景(3):第三方库、框架本身的限制。比如sql语句的in 字句不能过长,否则会导致SQL异常。这种情况下,可能需要分多次进行查询。
为此,本人在项目中封装了一个专门对List进行分页的工具类,同时也贡献出来,希望对某些人有用!!!
(1)抽象父类:
package com.lihong.DDPush; /** * Created by lihong10 on 2017/11/28. */ import java.util.Arrays; import java.util.List; public class UnRepeatablePage<T> extends Page<T> { public UnRepeatablePage(List<T> data, int pageSize) { this(data, 1, pageSize); } public UnRepeatablePage(List<T> data, int pageNo, int pageSize) { super(data, pageNo, pageSize); } @Override public boolean hasNext() { return cursor < this.totalPage; } @Override public List<T> next() { cursor++; if (data == null) { return null; } List<T> subList = null; if (data.size() > pageSize) { subList = data.subList(0, pageSize); data = data.subList(pageSize, data.size()); } else { subList = data.subList(0, data.size()); data = null; } return subList; } public void check() { if (cursor > 0) { throw new IllegalStateException("the operation is not permitted if for cycle or next() method has benn called before "); } } @Override public void reset() { throw new UnsupportedOperationException("reset is not permitted !!!,if you have not, use RepeatablePage.class"); } @Override public void reset(int cursor) { throw new UnsupportedOperationException("reset is not permitted !!!,if you have not, use RepeatablePage.class "); } public static void main(String[] args) { List<Integer> list = Arrays.asList(new Integer[]{0, 1, 2, 3, 4, 5, 6}); int pageSize = 6;//遍历分页时候,指定分页大小是3 UnRepeatablePage<Integer> page = new UnRepeatablePage<Integer>(list, 3); System.out.println("------------遍历前允许直接获取某一页------------------------"); System.out.println(page.getPage(2)); System.out.println("第1次遍历结果是"); for (List<Integer> li : page) { //for遍历 System.out.println(li); } System.out.println("------------遍历过之后,不允许直接获取某一页------------------------"); System.out.println(page.getPage(2)); page.reset();//调用reset会抛出异常,应为该子类不允许这个操作 for (List<Integer> li : page) { //for遍历 System.out.println(li); } } }
(2)可重复分页的子类及示例:
package com.lihong.DDPush; /** * Created by lihong10 on 2017/11/28. */ import java.util.Arrays; import java.util.List; public class RepeatablePage<T> extends Page<T> { public RepeatablePage(List<T> data, int pageSize) { this(data, 1, pageSize); } public RepeatablePage(List<T> data, int currentPage, int pageSize) { super(data, currentPage, pageSize); } @Override public boolean hasNext() { if (totalPage <= 0) { return false; } return cursor < totalPage; } @Override public List<T> next() { int pageNo = this.cursor + 1; List<T> page = getPage(pageNo); this.cursor++; return page; } public void check() { } public void reset() { this.cursor = 0; } public void reset(int cursor) { if (cursor < 0) { this.cursor = 0; } else if (cursor >= totalPage) { this.cursor = totalPage; } else { this.cursor = cursor; } } public static void main(String[] args) { List<Integer> list = Arrays.asList(new Integer[]{0, 1, 2, 3, 4, 5, 6}); int pageSize = 3;//遍历分页时候,指定分页大小是3 RepeatablePage<Integer> page = new RepeatablePage<Integer>(list, pageSize); System.out.println("------------直接获取某一页------------------------"); System.out.println(page.getPage(1)); System.out.println(page.getPage(2)); System.out.println(page.getPage(3)); System.out.println("第1次遍历结果是"); for (List<Integer> li : page) { //for遍历 System.out.println(li); } System.out.println("第2次遍历结果是"); page.reset(); for (List<Integer> li : page) { //遍历前调用了重置状态的reset方法,可以再次从头开始遍历 System.out.println(li); } System.out.println("第3次遍历结果是"); for (List<Integer> li : page) { //遍历前没有调用reset方法,遍历失败 System.out.println(li); } } }
(3)不可重复分页的子类及示例:
package com.lihong.DDPush; /** * Created by lihong10 on 2017/11/28. */ import java.util.Arrays; import java.util.List; public class UnRepeatablePage<T> extends Page<T> { public UnRepeatablePage(List<T> data, int pageSize) { this(data, 1, pageSize); } public UnRepeatablePage(List<T> data, int pageNo, int pageSize) { super(data, pageNo, pageSize); } @Override public boolean hasNext() { return cursor < this.totalPage; } @Override public List<T> next() { cursor++; if (data == null) { return null; } List<T> subList = null; if (data.size() > pageSize) { subList = data.subList(0, pageSize); data = data.subList(pageSize, data.size()); } else { subList = data.subList(0, data.size()); data = null; } return subList; } public void check() { if (cursor > 0) { throw new IllegalStateException("the operation is not permitted if for cycle or next() method has benn called befor this "); } } @Override public void reset() { throw new UnsupportedOperationException("reset is not permitted !!!,if you have not, use RepeatablePage.class"); } @Override public void reset(int cursor) { throw new UnsupportedOperationException("reset is not permitted !!!,if you have not, use RepeatablePage.class "); } public static void main(String[] args) { List<Integer> list = Arrays.asList(new Integer[]{0, 1, 2, 3, 4, 5, 6}); int pageSize = 6;//遍历分页时候,指定分页大小是3 UnRepeatablePage<Integer> page = new UnRepeatablePage<Integer>(list, 3); System.out.println("------------遍历前允许直接获取某一页------------------------"); System.out.println(page.getPage(2)); System.out.println("第1次遍历结果是"); for (List<Integer> li : page) { //for遍历 System.out.println(li); } System.out.println("------------遍历过之后,不允许直接获取某一页------------------------"); System.out.println(page.getPage(2)); page.reset();//调用reset会抛出异常,应为该子类不允许这个操作 for (List<Integer> li : page) { //for遍历 System.out.println(li); } } }
相关文章推荐
- 将一个list进行分页处理数据
- C++中两个线程用同一个list进行数据传递
- java中对list集合中的数据按照某一个属性进行分组
- 一个list集合列表绑入repeater进行分页
- json数据与JAVA数据的转换 jsonJavaBean.netApache 自己编写了一个工具类,处理页面提交json格式数据到后台,再进行处理成JAVA对象数据 1、DTO:Data T
- 对查询得到的List数据,进行分页操作
- 用jsp进行数据分页显示的一个实现
- 利用redis缓存对 list集合中的数据 进行分页操作(一)
- 利用redis缓存对 list集合中的数据 进行分页操作
- Django的Web页面上对list数据进行自定义分页
- java中对list进行分页显示数据到页面
- 定义一个List集合并实例化对应的实现类对象。循环输入任意个整数,输入0结束输入循环,对集合中的数据进行从大到小的排序后输出
- 将List中数据放入实体类中再放入List中(对List数据中进行分页处理)
- java中对list进行分页,并将显示数据到页面
- 编写了一个支持firefox和ie的javascript+xml进行数据分页的程序
- List<T>的一个数据分页,对分页数据有帮助
- 【用jsp进行数据分页显示的一个实现】
- 一个关于Json数据List和对象嵌套反序列化的工具类,java(20151130)
- 用jsp进行数据分页显示的一个实现
- 用jsp进行数据分页显示的一个实现