Springboot List集合如何用指定大小分组?

本文探讨了如何用Java编程解决将List按每4条数据分组的问题,并重点讲述了处理边界条件以确保不会遗漏数据的方法。作者通过实例展示了如何计算起始位置和结束位置,以确保在21条数据中完整展示每4行,避免了数据截取问题。
摘要由CSDN通过智能技术生成

    最近遇到这么一个需求数一个List有21条数据按照每4条显示出来,试了一些现成的工具不好用于是自己就写了一个分组方法。

1、实现思路



   假如有21条用户数据,现在要每4条数据为一行,共6行数据,且第一行从0开始推算如下:
演算推导
由图中得知从第二行开始每一行的系数(集合是从0开始遍历)与第一行比相差1倍col第三行与第二行比相差1倍col以此类推上一个与下一个都是相差1倍col。假设i表示行号,start 表示每行开始位置,end表示每行结束位置,推导如下:

int col  = 4;
int start = i*col;
int end = (i+1)*col
int row = list.size()/col;

不过int row = list.size()/col;的商不管是1.2 还是1.9都得向前进一也是就是都是2行,所以这里还需要改一下。可以使用java Math工具来处理。

/ **       @return  the smallest (closest to negative infinity)
*          floating-point value that is greater than or equal to
*          the argument and is equal to a mathematical integer.
*/
Math.ceil(double v1) 是返回一个大于或等于参数且等于数学整数的最小(最接近负无穷大)浮点值

2、为什么数据显示不全


List<String> str =   Arrays.asList("1","2","3","4","5","6","7","8","9","10",
            "11","12","13","14","15","16","17","18","19","20","21");
    List<String> groupLastList = new ArrayList<>();
    List<String> groupList = null;
    int row = (int) Math.ceil((double) str.size() / 4);
    System.out.println("行数:"+row);
    int col = 4;
    for (int i = 0; i < row; i++) {
        groupList = (i == BigInteger.ZERO.intValue()) ? str.subList(i, col) : getNextTeamList(str, col, i);
       StringBuilder builder = new StringBuilder(32);
        for (String m : groupList) {
            builder.append(m);
        }
        groupLastList.add(builder.toString());
    }
    System.out.println("每行数据:"+groupLastList.toString());

}
private static List<String> getNextTeamList(List<String> list1, int col, int i) {
    int size = list1.size();
    int rol = (i + 1);
    // 验证最后位置
    int endValue = rol * col;
    return (endValue <= size) ? list1.subList(col * i, endValue) : new ArrayList<String>();
}

输出结果:

行数:6
每行数据:[1234, 5678, 9101112, 13141516, 17181920, ]

从结果中我们看到第21条数据不见了,这是为什么呢?在思路演算1中提到 end = (i+1)*col,以数据size为21条为列,根据 end = (i+1)*col所得(5+1)*4=24然而集合size只有21条这样就会导致第21条数显示不出来。这样程序就出现了bug。基于这样的原因我们不得不考虑计算结束位置的边界。

3、何时才不截取数据?



      当 end-size>0时说明end值已经超出集合的size,根据上面的分析此时end肯定不是边界,假设集合有21条数据第6行就是第21条数据,根据公式可得 end = (i+1)colend为24,由上观察得知*(end-size)<col 即(24-21)<col** 时就能截取到数据,程序如下

/**
 * 截取集合,起始序号不是0
 * @param list1
 * @param col   列数
 * @param i     行号
 * @return List<Map < String, Object>>
 */
private static List<String> getNextTeamList(List<String> list1, int col, int i) {
    int size = list1.size();
    int rol = (i + 1);
    // 验证最后位置
    int  endValue = getEndPoint(rol,col,size);
    return (endValue <= size) ? list1.subList(col * i, endValue) : new ArrayList<String>();
}

private static int getEndPoint(int rol, int col, int size){
    int endValue = rol * col; 
    endValue = dealEndPoint(col,size,endValue);
    return endValue;
}

private static int dealEndPoint(int col, int size, int endValue){
    int diffences = endValue - size;
    return (diffences > 0 && diffences<=col)?endPoint(endValue,diffences):endValue;
}

private static int endPoint(int endValue, int diffences){
    return  endValue - diffences;
}

输出结果

行数:6
每行数据:[1234, 5678, 9101112, 13141516, 17181920, 21]

这次输出中第21条数据打印出来了。

4、总结



集合循环从0开始

  • 运用代入法推导公式
  • 集合根据指定数量分组需要考虑截取的起始点,和结束点的边界
  • 除第一条以外起点为start = col * i,col指定数量,i 循环的行数
  • 结束点end为int endValue = rol * col; rol = (i + 1)为行号,col为指定数量
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值