均匀地将列表分发到Java的子列表中

use*_*022 3 java arrays algorithm

我想将列表均匀分布到给定数量的子列表中.例如,我有一个包含元素1到10的列表,我想要3个列表.这些应该是这样的:

SL1 -> {1, 2, 3, 4}
SL2 -> {5, 6, 7}
SL3 -> {8, 9, 10}
Run Code Online (Sandbox Code Playgroud)

重要提示:每个列表包含的内容不相关,即SL1可能具有{1,5,7,10}.最重要的是有2个大小为3的列表和1个大小为4的列表.

我尝试了几件事,包括Iterables.partition但不会有所帮助.

我提出的唯一有用的是:

public Iterable<List<Integer>> distributeEvenlyQueryListIntoLists(final LinkedList<Integer> bigList, final Integer numberOfSublists) {
    List<List<Integer>> result = new ArrayList<>();

    // Creates as many lists as needed
    for (int i = 0; i < numberOfSublists; i++) {
        result.add(new ArrayList<>());
    }

    while (bigList.iterator().hasNext()) {
        for (int i = 0; i < numberOfSublists; i++) {
            if (!bigList.iterator().hasNext()) {
                break;
            }
            result.get(i).add(bigList.poll());
        }
    }
    return result;
}
Run Code Online (Sandbox Code Playgroud)

通过的bigList不一定是LinkedList,它可以是任何Iterable.

我特别讨厌创建子列表的第一个循环.

谢谢!

Pau*_*aul 5

只需以循环模式分发它们:

public <T> List<List<T>> partition(Iterable<T> iterable, int partitions){
    List<List<T>> result = new ArrayList<>(partitions);
    for(int i = 0; i < partitions; i++)
        result.add(new ArrayList<>());

    Iterator<T> iterator = iterable.iterator()
    for(int i = 0; iterator.hasNext(); i++)
        result.get(i % partitions).add(iterator.next());

    return result;
}
Run Code Online (Sandbox Code Playgroud)

使用此代码运行的示例:

List<String> l = Stream.iterate(0, i->i + 1).limit(25).map(i->Integer.toString(i)).collect(Collectors.toList());
System.out.println(partition(l, 4).toString());
Run Code Online (Sandbox Code Playgroud)

产生

[[0,4,8,12,16,20,24],[1,5,9,13,17,21],[2,6,10,14,18,22],[3,7, 11,15,19,23]]

基本思想是向结果集中的每个列表添加单个元素.这样可以保证两个列表之间元素数量的差异不会超过1.

作为替代方案,您可以使用Iterables.partition的 guavas实现,这需要稍微不同的方法.