有時候,我們需要將大的集合按指定的數量分割成若干個小集合。(比如:集合作為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(); } } }