在Java中對List進行分區(qū)的實現(xiàn)方法
1. 概述
在本文中,我們將說明如何將一個列表拆分為多個給定大小的子列表。
對于這個相對簡單的操作,標準 Java
集合 API 竟然不支持它。幸運的是,Guava
和 Apache-Commons
都提供了對應的 API 。
2. 使用 Guava 對 List 進行分區(qū)
Guava 通過Lists.partition 操作將 List 劃分為指定大小 的子列表:
List<Integer> intList = Lists.newArrayList(1, 2, 3, 4, 5, 6, 7, 8); List<List<Integer>> subSets = Lists.partition(intList, 3); subSets.forEach(s -> log.info("{}", s)); List<Integer> lastPartition = subSets.get(2); List<Integer> expectedLastPartition = Lists.newArrayList(7, 8); Assertions.assertEquals(subSets.size(), 3); Assertions.assertEquals(lastPartition, expectedLastPartition);
下面是我們得到的輸出結果:
[1, 2, 3]
[4, 5, 6]
[7, 8]
3. 使用 Guava 對集合進行分區(qū)
Guava 也可以對集合進行分區(qū):
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.newArrayList(1, 2, 3); Assertions.assertEquals(firstPartition, expectedLastPartition);
請記住,分區(qū)是原始集合的子列表視圖, 這意味著原始集合中的更改將反映在分區(qū)中:
@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)); }
4. 使用 Apache Commons Collections 對列表進行分區(qū)
Apache Commons Collections 的最新版本最近也添加了對列表分區(qū)的支持:
@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)); }
Commons Collections 沒有相應的選項來對原始集合進行分區(qū), 類似于 Guava Iterables.partition。
最后,同樣的警告也適用于此:生成的分區(qū)是原始列表的視圖。
5. 使用Java8對列表進行分區(qū)
現(xiàn)在讓我們看看如何使用 Java8 對我們的 List 進行分區(qū)。
5.1 收集器分區(qū)方式
我們可以使用Collectors.partitioningBy() 將列表拆分為 2 個子列表:
@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)); }
注意:生成的分區(qū)不是主列表的視圖,因此主列表發(fā)生的任何更改都不會影響分區(qū)。
5.2 收藏家分組方式
我們還可以使用Collectors.groupingBy() 將我們的列表分成多個分區(qū):
@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)); }
注意:與Collectors.partitioningBy() 一樣, 生成的分區(qū)不會受到主列表更改的影響。
5.3 按分隔符拆分列表
我們還可以使用 Java8 按分隔符拆分我們的列表:
@Test public void givenList_whenSplittingBySeparator_thenCorrect() { List<Integer> intList = Lists.newArrayList(1, 2, 3, 0, 4, 5, 6, 0, 7, 8); int[] indexes = Stream.of(IntStream.of(-1), IntStream.range(0, intList.size()) .filter(i -> intList.get(i) == 0), IntStream.of(intList.size())) .flatMapToInt(s -> s).toArray(); List<List<Integer>> subSets = IntStream.range(0, indexes.length - 1) .mapToObj(i -> intList.subList(indexes[i] + 1, indexes[i + 1])) .collect(Collectors.toList()); List<Integer> lastPartition = subSets.get(2); List<Integer> expectedLastPartition = Lists.<Integer> newArrayList(7, 8); assertThat(subSets.size(), equalTo(3)); assertThat(lastPartition, equalTo(expectedLastPartition)); }
注意:我們使用“0”作為分隔符。我們首先獲取了 List 中所有“0”元素的索引,然后我們根據(jù)這些索引拆分了List。
6. 結論
此處介紹的解決方案使用了額外的庫,即 Guava 和 Apache Commons Collections。這兩者都非常輕量級并且總體上非常有用,因此將其中之一放在類路徑中是非常有意義的。
到此這篇關于在Java中對List進行分區(qū)的實現(xiàn)方法的文章就介紹到這了,更多相關Java對List分區(qū)內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
SpringBoot 開發(fā)提速神器 Lombok+MybatisPlus+SwaggerUI
這篇文章主要介紹了SpringBoot 開發(fā)提速神器 Lombok+MybatisPlus+SwaggerUI,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2021-03-03Java多線程并發(fā)編程(互斥鎖Reentrant Lock)
這篇文章主要介紹了ReentrantLock 互斥鎖,在同一時間只能被一個線程所占有,在被持有后并未釋放之前,其他線程若想獲得該鎖只能等待或放棄,需要的朋友可以參考下2017-05-05Javaweb會話跟蹤技術Cookie和Session的具體使用
本文主要介紹了Javaweb會話跟蹤技術Cookie&Session的具體使用,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2022-07-07如何使用Java?8中DateTimeFormatter類型轉換日期格式詳解
這篇文章主要介紹了如何使用Java?8中DateTimeFormatter類型轉換日期格式詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-07-07