将一个list分红多个list

将一个list或其余集合按需分红多份,例如,分批发送等,是很常见的需求,可是Java传统的集合操做彷佛没有提供这一支持。apache

幸亏,google guava 和apache commons collections都提供了相应的实现。数据结构

方法一:guava实现,将一个list按三个一组分红N个小的list

代码块测试

[@Test](https://my.oschina.net/azibug)
​
public void givenList_whenParitioningIntoNSublists_thenCorrect() {
​
    List<Integer> intList = Lists.newArrayList(1, 2, 3, 4, 5, 6, 7, 8);
​
    List<List<Integer>> subSets = Lists.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));
​
}

方法二:guava分割其余collections

代码块google

[@Test](https://my.oschina.net/azibug)
​
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以后的结果也会随着改变。.net

代码块code

[@Test](https://my.oschina.net/azibug)
​
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](https://my.oschina.net/azibug)
​
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));
​
}
  1. 没有对应的Iterable.partions方法,相似guava那样
  2. partition后的结果一样是原集合的视图。

方法四:Java8方法。(在Java stream 中有讲。)

a.经过grouping byget

代码块it

[@Test](https://my.oschina.net/azibug)
​
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));
​
}

按年龄分组:io

代码块

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());
​
}

b.经过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的改变不会影响分组后的结果。
  2. partitioningBy 实际上是一种特殊的 groupingBy,它依照条件测试的是否两种结果来构造返回的数据结构,get(true) 和 get(false) 能即为所有的元素对象
相关文章
相关标签/搜索