有时候,我们需要将大的集合按指定的数量分割成若干个小集合。(比如:集合作为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. 使用Sqlserver Management Studio 导入导出 Excel的方法

    之前 帮同事  导入sql server数据     本来打算用 C# 写程序导入的 后来发现网上的方法  貌似 都会对版本  限制来限制去的 看的我好头晕(吐槽一下  难道就没有一个 普遍的方法嘛, ...

  2. angular Creating a Directive that Adds Event Listeners

    <span my-draggable>Drag ME</span> angular.module('dragModule', []) .directive('myDraggab ...

  3. 夺命雷公狗---微信开发59----在线点播电影网1之ckplayer播放器

    我们节课程就要开始写一个小项目了,这项目主要是写一个在线点播电影影网的,我们用到的播放器是ckplayer ckplayer基本介绍: ckplayer的全称是:超酷flv播放器,他是一款用于网页上播 ...

  4. 夺命雷公狗jquery---3普通选择器

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...

  5. 7. 星际争霸之php设计模式--中介者模式

    题记==============================================================================本php设计模式专辑来源于博客(jymo ...

  6. [JAVA]在linux中设置JDK环境,ZendStudio,Eclipse

    1.准备JDK安装包 下载地址: http://www.oracle.com/technetwork/java/javase/downloads/index.html 下载对应平台的tar.gz格式压 ...

  7. Windows应用层网络模块扫盲

           说到Windows应用层网络通信不得不提winsock,winsock是工作在TCP/IP层的应用层(TCP/IP层分为主机到网络层[比特].网络互联层[数据帧].传输层[数据包].应用 ...

  8. 5 Best Automation Tools for Testing Android Applications

    Posted In | Automation Testing, Mobile Testing, Software Testing Tools   Nowadays automated tests ar ...

  9. django form使用学习记录

    Django forms使用容易, 又方便扩展, 因此Django admin和CBVs基本都基于forms使用. 事实上, 由于django forms的强大验证功能, 大多数Django API ...

  10. linux-kernel 学习计划

    [资料] http://www.ibm.com/developerworks/cn/views/linux/libraryview.jsp http://www.kerneltravel.net/ [ ...