有时候,我们需要将大的集合按指定的数量分割成若干个小集合。(比如:集合作为SQL中IN的参数,而SQL又有长度限制,所以需要分批分几次进行查询)

虽然此需求感觉不常见,但偶也写过几次类似的方法,故记录之。

更新于2017年:其实Guava库有个已有的方法实现此需求:Lists.partition(List<T> list, int size)

v2,更新于2016-01-20

v1的代码使用后发现有问题,如果对分组后的一子集作删除操作,其他子集用迭代器遍历时会出现ConcurrentModificationException。

修改后的代码如下:

import java.util.ArrayList;
import java.util.List; public class CollectionGroupUtil { public static List groupListByQuantity(List list, int quantity) {
if (list == null || list.size() == 0) {
return list;
} if (quantity <= 0) {
new IllegalArgumentException("Wrong quantity.");
} List wrapList = new ArrayList();
int count = 0;
while (count < list.size()) {
wrapList.add(new ArrayList(list.subList(count, (count + quantity) > list.size() ? list.size() : count + quantity)));
count += quantity;
} return wrapList;
} }
import java.util.ArrayList;
import java.util.List; import org.junit.Test; public class CollectionGroupUtilTest { /**
* 大于分组数量的情况
*/
@Test
public void test() {
List<String> allList = new ArrayList<String>();
for (int i = 1; i <= 504; i++) {
allList.add(i + "");
} List<List<String>> groupList = CollectionGroupUtil.groupListByQuantity(allList, 50);
int i = 0;
List<String> list = null;
for (int c = 0; c < groupList.size(); c++) {
list = groupList.get(c); System.out.println("第" + (c + 1) + "组: ");
for (String temp : list) {
System.out.print(temp + ", ");
}
System.out.println();
}
} /**
* 小于分组数量的情况
*/
@Test
public void test2() {
List<String> allList = new ArrayList<String>();
for (int i = 1; i <= 45; i++) {
allList.add(i + "");
} List<List<String>> groupList = CollectionGroupUtil.groupListByQuantity(allList, 50);
int i = 0;
List<String> list = null;
for (int c = 0; c < groupList.size(); c++) {
list = groupList.get(c); System.out.println("第" + (c + 1) + "组: ");
for (String temp : list) {
System.out.print(temp + ", ");
}
System.out.println();
}
} /**
* 集合只有一个记录的情况
*/
@Test
public void test3() {
List<String> allList = new ArrayList<String>();
for (int i = 1; i <= 1; i++) {
allList.add(i + "");
} List<List<String>> groupList = CollectionGroupUtil.groupListByQuantity(allList, 50);
int i = 0;
List<String> list = null;
for (int c = 0; c < groupList.size(); c++) {
list = groupList.get(c); System.out.println("第" + (c + 1) + "组: ");
for (String temp : list) {
System.out.print(temp + ", ");
}
System.out.println();
}
} /**
* 空集合的情况
*/
@Test
public void test4() {
List<List<String>> groupList = CollectionGroupUtil.groupListByQuantity(null, 50);
System.out.println(groupList); groupList = CollectionGroupUtil.groupListByQuantity(new ArrayList(), 50);
System.out.println(groupList);
} /**
* 集合刚满一个分组的情况
*/
@Test
public void test5() {
List<String> allList = new ArrayList<String>();
for (int i = 1; i <= 50; i++) {
allList.add(i + "");
} List<List<String>> groupList = CollectionGroupUtil.groupListByQuantity(allList, 50);
int i = 0;
List<String> list = null;
for (int c = 0; c < groupList.size(); c++) {
list = groupList.get(c); System.out.println("第" + (c + 1) + "组: ");
for (String temp : list) {
System.out.print(temp + ", ");
}
System.out.println();
}
} /**
* 出现ConcurrentModificationException的情况
*/
@Test
public void test6() {
List<String> allList = new ArrayList<String>();
for (int i = 1; i <= 55; i++) {
allList.add(i + "");
} List<List<String>> groupList = CollectionGroupUtil.groupListByQuantity(allList, 50);
groupList.get(0).remove(0); int i = 0;
List<String> list = null;
for (int c = 0; c < groupList.size(); c++) {
list = groupList.get(c); System.out.println("第" + (c + 1) + "组: ");
for (String temp : list) {
System.out.print(temp + ", ");
}
System.out.println();
}
} }

以简单的方式重现ConcurrentModificationException异常:

import java.util.ArrayList;
import java.util.List; public class SeeConcurrentModificationExceptionInSubList { public static void main(String[] args) {
List<String> originalList = new ArrayList<String>();
for (int i = 1; i <= 5; i++) {
originalList.add(i + "");
} List<String> subList1 = originalList.subList(0, 3);
List<String> subList2 = originalList.subList(3, originalList.size()); /* 按坐标删除 */
subList1.remove(0); /* 用迭代器删除 */
/*
Iterator<String> i = subList1.iterator();
i.next();
i.remove();
*/ System.out.println("subList1 -> ");
for (String tempStr : subList1) {
System.out.println(tempStr);
} System.out.println("subList2 -> ");
for (String tempStr : subList2) {
System.out.println(tempStr);
} } }

v1,更新于2016-01-18

工具类

import java.util.ArrayList;
import java.util.List; public class CollectionGroupUtil { public static List groupListByQuantity(List list, int quantity) {
if (list == null || list.size() == 0) {
return list;
} if (quantity <= 0) {
new IllegalArgumentException("Wrong quantity.");
} List wrapList = new ArrayList();
int count = 0;
while (count < list.size()) {
wrapList.add(list.subList(count, (count + quantity) > list.size() ? list.size() : count + quantity));
count += quantity;
} return wrapList;
} }

测试类

import java.util.ArrayList;
import java.util.List; import org.junit.Test; public class CollectionGroupUtilTest { /**
* 大于分组数量的情况
*/
@Test
public void test() {
List<String> allList = new ArrayList<String>();
for (int i = 1; i <= 504; i++) {
allList.add(i + "");
} List<List<String>> groupList = CollectionGroupUtil.groupListByQuantity(allList, 50);
int i = 0;
List<String> list = null;
for (int c = 0; c < groupList.size(); c++) {
list = groupList.get(c); System.out.println("第" + (c + 1) + "组: ");
for (String temp : list) {
System.out.print(temp + ", ");
}
System.out.println();
}
} /**
* 小于分组数量的情况
*/
@Test
public void test2() {
List<String> allList = new ArrayList<String>();
for (int i = 1; i <= 45; i++) {
allList.add(i + "");
} List<List<String>> groupList = CollectionGroupUtil.groupListByQuantity(allList, 50);
int i = 0;
List<String> list = null;
for (int c = 0; c < groupList.size(); c++) {
list = groupList.get(c); System.out.println("第" + (c + 1) + "组: ");
for (String temp : list) {
System.out.print(temp + ", ");
}
System.out.println();
}
} /**
* 集合只有一个记录的情况
*/
@Test
public void test3() {
List<String> allList = new ArrayList<String>();
for (int i = 1; i <= 1; i++) {
allList.add(i + "");
} List<List<String>> groupList = CollectionGroupUtil.groupListByQuantity(allList, 50);
int i = 0;
List<String> list = null;
for (int c = 0; c < groupList.size(); c++) {
list = groupList.get(c); System.out.println("第" + (c + 1) + "组: ");
for (String temp : list) {
System.out.print(temp + ", ");
}
System.out.println();
}
} /**
* 空集合的情况
*/
@Test
public void test4() {
List<List<String>> groupList = CollectionGroupUtil.groupListByQuantity(null, 50);
System.out.println(groupList); groupList = CollectionGroupUtil.groupListByQuantity(new ArrayList(), 50);
System.out.println(groupList);
} /**
* 集合刚满一个分组的情况
*/
@Test
public void test5() {
List<String> allList = new ArrayList<String>();
for (int i = 1; i <= 50; i++) {
allList.add(i + "");
} List<List<String>> groupList = CollectionGroupUtil.groupListByQuantity(allList, 50);
int i = 0;
List<String> list = null;
for (int c = 0; c < groupList.size(); c++) {
list = groupList.get(c); System.out.println("第" + (c + 1) + "组: ");
for (String temp : list) {
System.out.print(temp + ", ");
}
System.out.println();
}
} }

【Java】List集合按数量分组的更多相关文章

  1. 【Java工具方法】给集合按数量分组

    有时候需要给集合(如List)按数量分组,比如全集太大时,需要分批处理:或效率有点低,分批并发处理.于是,写了个将List按数量分组的方法. package controller; import ja ...

  2. 【Java】集合_学习笔记

    一.集合 1.集合类也称容器类,主要负责保存.盛装其他数据. 2.集合可以保存数量不确定的数据,保存具有映射关系的数据(也称关联数组). 3.Java5后提供一些多线程安全的集合类,放在java.ut ...

  3. Java之集合初探(一)

    一.集合概述.区别 集合是一种容器,数组也是一种容器 在Java编程中,装各种各样的对象(引用类型)的叫做容器. 为什么出现集合类? 面向对象语言对事物的体现都是以对象的形式,所以为了方便对多个对象的 ...

  4. java各种集合的线程安全

    微信公众号[程序员江湖] 作者黄小斜,斜杠青年,某985硕士,阿里 Java 研发工程师,于 2018 年秋招拿到 BAT 头条.网易.滴滴等 8 个大厂 offer,目前致力于分享这几年的学习经验. ...

  5. 对JAVA的集合的理解

    对JAVA的集合的理解是相对于数组 1.数组是大小固定的,并且同一个数组只能存放类型一样的数据(基本类型/引用类型) 2.JAVA集合可以存储和操作数目不固定的一组数据.  3.所有的JAVA集合都位 ...

  6. Java中集合的概述

    一.集合和数组的区别 1.数组(可以存储基本数据类型)是用来存现对象的一种容器,但是数组的长度固定,不适合在对象数量未知的情况下使用. 2.集合(只能存储对象,对象类型可以不一样)的长度可变,可在多数 ...

  7. [Java复习] 集合框架 Collection

    Q1 Collection java的集合以及集合之间的继承关系? 数组和链表的区别? 固定长度,连续内存,不能扩展,随机访问快,插入删除慢.链表相反 List, Set, Map的区别? List, ...

  8. Java小白集合源码的学习系列:LinkedList

    目录 LinkedList 源码学习 LinkedList继承体系 LinkedList核心源码 Deque相关操作 总结 LinkedList 源码学习 前文传送门:Java小白集合源码的学习系列: ...

  9. java的集合框架最全详解

    java的集合框架最全详解(图) 前言:数据结构对程序设计有着深远的影响,在面向过程的C语言中,数据库结构用struct来描述,而在面向对象的编程中,数据结构是用类来描述的,并且包含有对该数据结构操作 ...

随机推荐

  1. android中获取打气筒的几种方式

    1,简单说明,打气筒就是将我们的xml布局转换为我们的view对象,不扯远了,直接看代码 A:从context中获取 LayoutInflater inflater1 = LayoutInflater ...

  2. Java内部类小程序(成员内部类,静态内部类,匿名内部类)

    /** * 测试java内部类(成员内部类,静态内部类,匿名内部类) * 局部内部类不常用,就不写了. * @package :java05 * @author shaobn * @Describe ...

  3. java使用json将HashMap转化成javabean小例子

    import java.util.HashMap; import java.util.Iterator; import java.util.Map; import net.sf.json.JSONOb ...

  4. Dr.Kong的艺术品

    题目 Dr.Kong设计了一件艺术品,该艺术品由N个构件堆叠而成,N个构件从高到低按层编号依次为1,2,……,N.艺术品展出后,引起了强烈的反映.Dr.Kong观察到,人们尤其对作品的高端部分评价甚多 ...

  5. WCF和Web Service的 区(guan)别(xi)

    参考文献:http://social.microsoft.com/Forums/zh-CN/c06420d1-69ba-4aa6-abe5-242e3213b68f/wcf-webservice 之前 ...

  6. OpenCV cv::Mat类

    using namespace cv; 1.Mat的声明: Mat m=Mat(rows, cols, type); Mat m=Mat(Size(width,height), type); type ...

  7. Sql Server 2012 的新分页方法分析(offset and fetch) - 转载

    最近在分析 Sql Server 2012 中 offset and fetch 的新特性,发现 offset and fetch 无论语法的简洁还是功能的强大,都是相当相当不错的 其中 offset ...

  8. LoadRunner11下载以及详细破解说明【最新】

    Loadrunner11破解所需两个dll文件以及自动删除注册表工具,使用方法见附件readme.也可安装网上的办法,手动删除注册表项. 下载破解文件lm70.dll和mlr5lprg.dll lm7 ...

  9. 内存映射MMAP和DMA【转】

    转自:http://blog.csdn.net/zhoudengqing/article/details/41654293 版权声明:本文为博主原创文章,未经博主允许不得转载. 这一章介绍Linux内 ...

  10. awr报告生成方法

    以上是在linux的oracle的命令截图. 如果是在unix的命令,则需要在命令前面加上\符号,变成了\@$ORACLE_HOME/rdbms/admin/awrrpt.sql