在java中,如果可能的话,使用flatmap将列表拆分为子列表

zsohkypk  于 2021-06-29  发布在  Java
关注(0)|答案(5)|浏览(656)

这个问题在这里已经有答案了

如何将数组列表等分(9个答案)
8天前关门了。
以下是我的清单:

List<Integer> mylist = Arrays.asList(1,2,3,4,5,6,7,8,9,10,11,12);

假设我的列表总是偶数,那么我想把它分成6等份。
以草图形式列出:

[1,2,3,4,5,6,7,8,9,10,11,12]

输出草图:

[[1,2][3,4],[5,6],[7,8],[9,10],[11,12]]

如果可能的话,我更喜欢使用Java8流的解决方案 flatMap

xtfmy6hx

xtfmy6hx1#

如果你真的想用flatmap来解决问题,你可以尝试这样的方法,但不是一个直观的解决方案。最后,它只需要返回一个流,所以这只是在进程中构造子列表,并在最后作为流返回。
顺便说一句,我个人更喜欢Guava Lists.partition ```
List result = list.stream().flatMap(new Function<>() {

             List<List<Integer>> mainList = new ArrayList<>();
             List<Integer> subList = new ArrayList<>(2);
             int index = 0;

             @Override
             public Stream<?> apply(Integer integer) {
                 subList.add(integer);

                 if ((index + 1) % 2 == 0) {
                     mainList.add(subList);
                     subList = new ArrayList<>(2);
                 }
                 index++;
                 if (index == list.size()) {
                     if(!subList.isEmpty()) {
                         mainList.add(subList);
                     }
                     return mainList.stream();
                 }
                 return Stream.empty();
             }

         }).collect(Collectors.toList());
6ovsh4lw

6ovsh4lw2#

以下内容适用于从1到 size of the list . 如果组大小没有平均划分列表大小,那么剩余的将被放入自己的组中。
另外,额外的 map(ArrayList::new) 确保子列表放在自己的列表中。否则,更改原始列表条目也会更改子列表条目。

int gsize = 2;
List<Integer> mylist =
        Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12);
    List<List<Integer>> subLists = IntStream
            .iterate(0, i -> i < mylist.size(),
                    i -> i + gsize)
            .mapToObj(i -> mylist.subList(i,
                    (i + gsize <= mylist.size()) ?
                            i + gsize : mylist.size()))
            .map(ArrayList::new)
            .collect(Collectors.toList());

System.out.println(subLists);

印刷品

[[1, 2], [3, 4], [5, 6], [7, 8], [9, 10], [11, 12]]

如果组大小为5,则新列表将如下所示:

[[1, 2, 3, 4, 5], [6, 7, 8, 9, 10], [11, 12]]
vi4fp9gy

vi4fp9gy3#

我知道这超出了范围,但另一种可能是使用像guava这样的库,它有很多与list相关的方法。
附属国

<dependency>
    <groupId>com.google.guava</groupId>
    <artifactId>guava</artifactId>
    <version>30.1-jre</version>
</dependency>

例子

package com.stackoverflow.question;

import java.util.Arrays;
import java.util.List;

import com.google.common.collect.Lists;

public class Question {
    public static void main(String[] args) {
        List<Integer> mylist = Arrays.asList(1,2,3,4,5,6,7,8,9,10,11,12);
        List<List<Integer>> partionList = Lists.partition(mylist, 2);

        System.out.println(partionList);
    }
}

输出

[[1, 2], [3, 4], [5, 6], [7, 8], [9, 10], [11, 12]]
vdgimpew

vdgimpew4#

假设“子列表”的大小都相等,并且您可以将列表划分为大小相同的精确子列表,您可以计算所需的大小,然后Map IntStream 到每个子列表的起始索引,并使用它来提取它们:

List<Integer> mylist = Arrays.asList(1,2,3,4,5,6,7,8,9,10,11,12);
int size = mylist.size();
int parts = 6;
int partSize = size / parts;
List<List<Integer>> result = 
    IntStream.range(0, parts)
             .mapToObj(i -> mylist.subList(i * partSize, (i + 1) * partSize)))
             .collect(Collectors.toList());

编辑:
ideone演示由@turing85提供

6tqwzwtp

6tqwzwtp5#

Stream -操作应该是无状态的。执行的任务本质上需要状态。因此,我建议不要使用 Stream . 相反,我建议 for -基于循环的解决方案:

public static List<List<Integer>> partition(
        List<Integer> list, 
        int partitionSize) {
    final int listSize = list.size();
    if (listSize % partitionSize != 0) {
        throw new IllegalArgumentException("The size of the list must be "
                + "divisible without remainder by the partition size.");
    }

    final List<List<Integer>> partition = new ArrayList<>();
    for (int start = 0; start < listSize; start += partitionSize) {
        partition.add(list.subList(start, start + partitionSize));
    }
    return partition;
}

ideone演示
如果我们坚持使用 Stream -基于实现,我建议使用mureinik给出的代码。

相关问题