java 中 list集合 截取 函数

29 篇文章 0 订阅
7 篇文章 0 订阅

Java list有几十万条数据,每100条为一组取出

解决“java 中 list集合中有几十万条数据,每100条为一组取出来如何实现,求代码!!!”的问题。

原文链接:实现java 中 list集合中有几十万条数据,每100条为一组取出

/**
* 实现java 中 list集合中有几十万条数据,每100条为一组取出
* @param list 可穿入几十万条数据的List
* @return map 每一Kye中有100条数据的List
*/
@SuppressWarnings({ "unchecked", "rawtypes" })
public Map groupList(List list){
        
    int listSize=list.size();
    int toIndex=100;
    Map map = new HashMap();     //用map存起来新的分组后数据
    int keyToken = 0;
    for(int i = 0;i<list.size();i+=100){
        if(i+100>listSize){        //作用为toIndex最后没有100条数据则剩余几条newList中就装几条
            toIndex=listSize-i;
        }
        List newList = list.subList(i,i+toIndex);
        map.put("keyName"+keyToken, newList);
        keyToken++;
    }
    return map;
}

以上代码存在问题,我自己使用中修复版,类似下面:

public Map groupList(List list){
    int listSize=list.size();//长度,暂定为 666
    int toIndex=100;
    Map map = new HashMap();     //用map存起来新的分组后数据
    int keyToken = 0;
    for(int i = 0;i<list.size();i+=100){
        if(i+100>listSize){        //作用为toIndex最后没有100条数据则剩余几条newList中就装几条
            toIndex=listSize-i;
        }
        //未切分,i:0,toIndex:100,list.size:666
        //List newList = list.subList(i,i+toIndex);
        //原第一次,i:0,toIndex:100,list.size:566
        //原第二次,i:100,toIndex:100,list.size:466
        //原第三次,i:200,toIndex:100,list.size:366
        //原第四次,报错下标越界,i:300,toIndex:100,list.size:266
        List newList = list.subList(0,toIndex);
        //修复版第一次,i:0,toIndex:100,list.size:566
        //修复版第一次,i:100,toIndex:100,list.size:466
        //修复版第一次,i:200,toIndex:100,list.size:366
        //修复版第一次,i:300,toIndex:100,list.size:266
        //修复版第一次,i:400,toIndex:100,list.size:166
        //修复版第一次,i:500,toIndex:100,list.size:66
        //修复版第一次,i:600,toIndex:66,list.size:0
        map.put("keyName"+keyToken, newList);
        keyToken++;
    }
    return map;
}

PS:2022.12.14,上面的代码确实有问题,重新试了下,确实只能提取前面的元素,源代码是正确的。抱歉是我考虑不周。

错误示例

正确示例

源码分析

下标验证

返回的是特殊的list实现

分析截止。

总结:网上的代码实现,最好还是要斟酌一下再用,防止坑到自己,最好只参考思路,自己实现一边最好。

NEW

参考

java8 Stream 大数据量List分批处理切割

Java8 Stream分割list集合

重新编写并测试的代码,含jdk8处理方式

public static void main(String[] args) {
    int size = 12,num = 5;
    List<Integer> list = new ArrayList<>(size);
    for (int i = 0; i < size; i++) { list.add(i); }
    // 每份5个
    System.out.println(split(list,num));
    System.out.println(split8(list,num));
    // 分割总份数5
    System.out.println(average(list,num));
    System.out.println(average8(list,num));
}
public static <T> List<List<T>> split( List<T> list,  int splitSize ) {
    // 每份个数 splitSize
    if( null == list || list.isEmpty() ){ return Collections.emptyList(); }
    // 列表元素数,分割结束下标,总份数
    int size = list.size(),toIndex  = splitSize, cnt = (size + splitSize - 1 ) / splitSize;
    List<List<T>> result = new ArrayList<>( cnt );
    for ( int i = 0; i < size ; i += splitSize ) {
        if( i + splitSize > size ){ toIndex = size - i; }
        result.add( list.subList( i , i + toIndex ) );
    }
    return result;
}
public static <T> List<List<T>> split8(List<T> list,int splitSize){
    // 每份个数 splitSize
    if( null == list || list.isEmpty() ){ return Collections.emptyList(); }
    // 列表元素数,总份数
    int size = list.size(), cnt = (size + splitSize - 1 ) / splitSize;
    return Stream
            .iterate(0,i -> i+1 )
            .limit(cnt)
            .parallel()
            .map(i -> list.parallelStream().skip( i * splitSize ).limit(splitSize).collect(Collectors.toList()))
            .filter(a -> !a.isEmpty())
            .collect(Collectors.toList());
}
public static <T> List<List<T>> average( List<T> list,  int splitCnt ) {
    // 总份数 splitCnt
    if( null == list || list.isEmpty() ){ return Collections.emptyList(); }
    // 列表元素数,余数(需要分配的前几份中),每份最少个数(前几份需要平分余数元素)
    int size = list.size(), r = size % splitCnt,sp = size / splitCnt;
    List<List<T>> result = new ArrayList<>( splitCnt );
    for (int i = 0; i < splitCnt; i++) {
        if( i < r ){
            result.add( list.subList(i * sp + (i % r), (i + 1 ) * sp + (i % r) + 1 ) );
        }else {
            result.add( list.subList(i * sp + r, (i + 1 ) * sp + r ) );
        }
    }
    return result;
}
public static <T> List<List<T>> average8(List<T> list,int splitCnt){
    // 总份数 splitCnt
    if( null == list || list.isEmpty() ){ return Collections.emptyList(); }
    // 列表元素数,余数(需要分配的前几份中),每份最少个数(前几份需要平分余数元素)
    int size = list.size(),r = size % splitCnt,sp = size / splitCnt;
    return Stream
            .iterate(0,i -> i+1 )
            .limit(splitCnt)
            .parallel()
            .map(i -> list.parallelStream().skip( i * sp + (i < r ? i % r : r ) ).limit(sp + ( i < r ? 1 : 0 )).collect(Collectors.toList()))
            .filter(a -> !a.isEmpty())
            .collect(Collectors.toList());
}

测试

[[0, 1, 2, 3, 4], [5, 6, 7, 8, 9], [10, 11]]
[[0, 1, 2, 3, 4], [5, 6, 7, 8, 9], [10, 11]]
[[0, 1, 2], [3, 4, 5], [6, 7], [8, 9], [10, 11]]
[[0, 1, 2], [3, 4, 5], [6, 7], [8, 9], [10, 11]]

 

 END

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值