java如何将list按照指定数量分成小list
作者:赶路人儿
本文介绍了四种不同的方法对集合进行分区操作,包括手动编写代码、使用Guava库、Apache Commons Collection库以及Java 8的流操作,每种方法都有其特点和适用场景,需要注意的是,部分方法返回的是原集合的视图,而部分则返回的是新的集合
java将list按照指定数量分成小list
自己编写相关代码:
使用guava
import java.util.ArrayList; import java.util.List; import com.google.common.collect.Lists; public class Test4 { public static void main(String[] args) { List<Long> list = new ArrayList<>(); list.add(1L); list.add(2L); list.add(3L); list.add(4L); list.add(5L); list.add(6L); list.add(7L); list.add(8L); list.add(9L); //test1(list); test2(list); } private static void test1(List<Long> list) { int size = 2; List<List<Long>> listArr = new ArrayList<>(); int arrSize = list.size()%size==0?list.size()/size:list.size()/size+1; for(int i=0;i<arrSize;i++) { List<Long> sub = new ArrayList<>(); for(int j=i*size;j<=size*(i+1)-1;j++) { if(j<=list.size()-1) { sub.add(list.get(j)); } } listArr.add(sub); } System.out.println(listArr.toString()); } private static void test2(List<Long> list) { int size = 16; List<List<Long>> subSets = Lists.partition(list, size); System.out.println(subSets.toString()); } }
补充:guava分割其他collectionsiew plain
@Test public void givenCollection_whenParitioningIntoNSublists_thenCorrect() { Collection<Integer> intCollection = Lists.newArrayList(1, 2, 3, 4, 5, 6, 7, 8); Iterable<List<Integer>> subSets = Iterables.partition(intCollection, 3); List<Integer> firstPartition = subSets.iterator().next(); List<Integer> expectedLastPartition = Lists.<Integer> newArrayList(1, 2, 3); assertThat(firstPartition, equalTo(expectedLastPartition)); }
以上需要注意的是:
partition返回的是原list的subview.视图,也即,原list改变后,partition之后的结果也会随着改变。
@Test public void givenListPartitioned_whenOriginalListIsModified_thenPartitionsChangeAsWell() { // Given List<Integer> intList = Lists.newArrayList(1, 2, 3, 4, 5, 6, 7, 8); List<List<Integer>> subSets = Lists.partition(intList, 3); // When intList.add(9); // Then List<Integer> lastPartition = subSets.get(2); List<Integer> expectedLastPartition = Lists.<Integer> newArrayList(7, 8, 9); assertThat(lastPartition, equalTo(expectedLastPartition)); }
使用apache commons collection
@Test public void givenList_whenParitioningIntoNSublists_thenCorrect() { List<Integer> intList = Lists.newArrayList(1, 2, 3, 4, 5, 6, 7, 8); List<List<Integer>> subSets = ListUtils.partition(intList, 3); List<Integer> lastPartition = subSets.get(2); List<Integer> expectedLastPartition = Lists.<Integer> newArrayList(7, 8); assertThat(subSets.size(), equalTo(3)); assertThat(lastPartition, equalTo(expectedLastPartition)); }
- 没有对应的Iterable.partions方法,类似guava那样
- partition后的结果同样是原集合的视图。
Java8方法
1)通过grouping by:
@Test public final void givenList_whenParitioningIntoNSublistsUsingGroupingBy_thenCorrect() { List<Integer> intList = Lists.newArrayList(1, 2, 3, 4, 5, 6, 7, 8); Map<Integer, List<Integer>> groups = intList.stream().collect(Collectors.groupingBy(s -> (s - 1) / 3)); List<List<Integer>> subSets = new ArrayList<List<Integer>>(groups.values()); List<Integer> lastPartition = subSets.get(2); List<Integer> expectedLastPartition = Lists.<Integer> newArrayList(7, 8); assertThat(subSets.size(), equalTo(3)); assertThat(lastPartition, equalTo(expectedLastPartition)); }
按年龄分组:
Map<Integer, List<Person>> personGroups = Stream.generate(new PersonSupplier()). limit(100). collect(Collectors.groupingBy(Person::getAge)); Iterator it = personGroups.entrySet().iterator(); while (it.hasNext()) { Map.Entry<Integer, List<Person>> persons = (Map.Entry) it.next(); System.out.println("Age " + persons.getKey() + " = " + persons.getValue().size()); }
2)通过partition by:
@Test public void givenList_whenParitioningIntoSublistsUsingPartitionBy_thenCorrect() { List<Integer> intList = Lists.newArrayList(1, 2, 3, 4, 5, 6, 7, 8); Map<Boolean, List<Integer>> groups = intList.stream().collect(Collectors.partitioningBy(s -> s > 6)); List<List<Integer>> subSets = new ArrayList<List<Integer>>(groups.values()); List<Integer> lastPartition = subSets.get(1); List<Integer> expectedLastPartition = Lists.<Integer> newArrayList(7, 8); assertThat(subSets.size(), equalTo(2)); assertThat(lastPartition, equalTo(expectedLastPartition)); }
按照成年未成年人分组:
Map<Boolean, List<Person>> children = Stream.generate(new PersonSupplier()). limit(100). collect(Collectors.partitioningBy(p -> p.getAge() < 18)); System.out.println("Children number: " + children.get(true).size()); System.out.println("Adult number: " + children.get(false).size());
注意:
1.Java8方式,分组后的list不再是原list的视图。所以,原list的改变不会影响分组后的结果。
2partitioningBy 其实是一种特殊的 groupingBy,它依照条件测试的是否两种结果来构造返回的数据结构,get(true) 和 get(false) 能即为全部的元素对象。
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。