list 集合 分页 三种实现方式,include jdk8 --stream

https://blog.csdn.net/mei3983646/article/details/82983230

第一种方法是循环截取某个页面的数据:

    /**
     * 循环截取某页列表进行分页
     * @param dataList 分页数据
     * @param pageSize  页面大小
     * @param currentPage   当前页面
     */
    public static List<String> page(List<String> dataList, int pageSize,int currentPage) {
        List<String> currentPageList = new ArrayList<>();
        if (dataList != null && dataList.size() > 0) {
            int currIdx = (currentPage > 1 ? (currentPage - 1) * pageSize : 0);
            for (int i = 0; i < pageSize && i < dataList.size() - currIdx; i++) {
                String data = dataList.get(currIdx + i);
                currentPageList.add(data);
            }
        }
        return currentPageList;
    }
第二种是利用List中的sublist方法进行分页:

注意:

List<E> subList(int fromIndex, int toIndex);
它返回原来list的从[fromIndex, toIndex)之间这一部分的视图,之所以说是视图,是因为实际上,返回的list是靠原来的list支持的。返回一个以fromIndex为起始索引(包含),以toIndex为终止索引(不包含)的子列表(List)。 
比如集合中的内容为1,2,3,4,5
 list.sublist(2,4)
就返回一个子集合:它的内容包括从下标为2到下标为4,而且这是左闭右开的
就是说是从大于等于2到小于4
那子集内容就是3,4(集合的下标都是从0开始);

    /**
     * 利用subList方法进行分页
     * @param list 分页数据
     * @param pagesize  页面大小
     * @param currentPage   当前页面
     */
    public static List<String> pageBySubList(List list, int pagesize, int currentPage) {
        int totalcount = list.size();
        int pagecount = 0;
        List<String> subList;
        int m = totalcount % pagesize;
        if (m > 0) {
            pagecount = totalcount / pagesize + 1;
        } else {
            pagecount = totalcount / pagesize;
        }
        if (m == 0) {
            subList = list.subList((currentPage - 1) * pagesize, pagesize * (currentPage));
        } else {
            if (currentPage == pagecount) {
                subList = list.subList((currentPage - 1) * pagesize, totalcount);
            } else {
                subList = list.subList((currentPage - 1) * pagesize, pagesize * (currentPage));
            }
        }
        return subList;
    }
测试结果:

    public static void main(String[] args) {
 
        List<String> list = new ArrayList<>();
        for (int i = 1; i <= 50; i++) {
            list.add(String.valueOf(i));
        }
 
        List<String> curList = page(list,6,2);
        List<String> subList = pageBySubList(list,6,2);
 
        System.out.println("page:"+curList);
        System.out.println("pageBySubList:" + subList);
 
    }
运行结果:

page:[7, 8, 9, 10, 11, 12]
pageBySubList:[7, 8, 9, 10, 11, 12]
--------------------- 
作者:PPCode 
来源:CSDN 
原文:https://blog.csdn.net/mei3983646/article/details/82983230 
版权声明:本文为博主原创文章,转载请附上博文链接!

https://blog.csdn.net/qq_28751497/article/details/82112463

话不多说,这里有一个常规的业务场景,我想根据从前端传来的几个字段,比如需要排序的字段、第几页、一页显示几条从后台取出对应的数据。 
如果说按照一般的做法,那肯定是在sql里面操作,取到对应的字段,我这里使用jdk1.8的语法

比如一个实体类

public class User{
 ........//这里省略实体类里面的字段,因为这个例子暂时不需要出现它们

假设我先从数据库里面查出来一个数据集合

List<User> list=..........;//从数据库查出
1
假设根据字段排序,那这要用到Comparator关键字

Comparator<User> comparator = Comparator.comparing(user -> {
          try {
            Field field = User.class.getDeclaredField(orderBy);//这里的orderBy就是前端传来的根据什么字段排序
            //这里使用的是反射的语法
            field.setAccessible(true);
            if (!Comparable.class.isAssignableFrom(field.getType())) {
              throw new BadRequestException("order_by:" + orderBy + "不可排序");
            }
            return (Comparable)field.get(user);
          } catch (NoSuchFieldException e) {
            throw new BadRequestException("order_by:" + orderBy + "不存在", e);
          } catch (IllegalAccessException e) {
            throw new InternalServerException(e);
          }
        });

最后一句话就可以搞定了:

list.stream().sorted(comparator).skip((pageNumber-1+1)* pageSize).limit(pageSize).collect(Collectors.toList())

这里说明一下,这里使用的是正序排列,如果是倒序排列,sorted(comparator.reversed()) 
pageNumber就是显示第几页,pageSize就是一页显示几条,这样数据就可以根据需求取出,不用再考虑页数问题导致的空数据,还要再去加判断条件去开发这个需求了。

这里我最后想谈谈我学习jdk1.8的一些感悟。 
1、很多人都说jdk1.8很多语法都是语法糖,我非常不同意这个观点。首先大家要知道jdk是谁开发的?jdk是oracle工程师开发的,我相信他们是这个行业最最顶尖的开发人员了吧,这些精英会无聊到开发一些仅仅是不同写法的东西吗?

2、我们回到语法本身,那jdk1.8到底好在哪里;第一,那就是对开发人员的方便。我们就拿这个需求来说,一般来说你要用Mybatis操作,是不是首先需要建立一个查询sql的接口,类似于Mapper,然后再建一个实现这个sql接口的实现类,最后才再mybatis中的xml里面写sql,这样一看如果写一句sql,要在三个文件里面操作,一旦需求改变了,开发人员就需要维护三个文件,这样在需求多的情况下自己都会手忙脚乱。

3、第二点,jdk1.8大大提升对数据库的性能,因为可以很少甚至不用去访问数据库了,比如我列的这个需求,不要看按字段排序需要那么麻烦,但是这仅仅是对java层面的操作,根本不用访问数据库。你要知道,根据字段排序的关键函数 order by 是非常损耗数据库的性能的,还有很多数据库里的关键函数比如,group by、sum等等都可以用jdk1.8语法所取代,这里就不多展开了。

4、最后呢,我想说,一种语言的语法不断改进肯定有开发者的理由,也许新语法还有这样或那样的不完善,但这也就是开发人员不断去更新不断追求完美的理由吧,这也需要大家的思考和钻研,而不是武断地认为新语法就一定不好或者一定好。
--------------------- 
作者:蓝斌星 
来源:CSDN 
原文:https://blog.csdn.net/qq_28751497/article/details/82112463 
版权声明:本文为博主原创文章,转载请附上博文链接!

  • 1
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
使用 JDK 8 中的 Stream API,你可以通过以下方式List 切割成三等分: ```java import java.util.ArrayList; import java.util.List; import java.util.stream.Collectors; import java.util.stream.IntStream; public class ListDivider { public static List<List<Integer>> divideList(List<Integer> originalList) { int totalSize = originalList.size(); int partitionSize = totalSize / 3; List<List<Integer>> dividedLists = IntStream.range(0, totalSize) .boxed() .collect(Collectors.groupingBy(index -> index / partitionSize)) .values() .stream() .map(indices -> indices.stream() .map(originalList::get) .collect(Collectors.toList())) .collect(Collectors.toList()); return dividedLists; } public static void main(String[] args) { List<Integer> originalList = new ArrayList<>(); originalList.add(1); originalList.add(2); originalList.add(3); originalList.add(4); originalList.add(5); originalList.add(6); originalList.add(7); originalList.add(8); originalList.add(9); List<List<Integer>> dividedLists = divideList(originalList); System.out.println(dividedLists); } } ``` 在上述示例中,我们使用 IntStream 来生成一个从 0 到 totalSize 的索引流。然后,我们通过 `groupingBy` 方法将索引按照 partitionSize 进行分组,将每个索引映射到对应的子列表。最后,我们通过 `map` 方法将索引转换为原始列表中的元素,并使用 `Collectors.toList()` 收集为子列表。最终,我们得到了包含三个切割后子列表的列表。 你可以运行示例代码来验证结果,输出应为 `[[1, 2, 3], [4, 5, 6], [7, 8, 9]]`。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值