如何使用N个分区而不是大小为N的分区对列表进行分区?

Jac*_* G. 1 java partitioning list guava

Guava的方法,Lists#partition将a分区List<?>为List<List<?>>每个分区包含N元素的位置(由函数的第二个参数指定,并排除最后一个分区).

是否可以使用此方法但是创建N分区呢?

如果没有,有什么方法可以解决它?

我试图创建31具有以下(分区keys是List<String>大小57),但它只会造成29:

List<String> keys = ...;

var paritions = Lists.partition(keys, (int) Math.ceil(keys.size() / 31D));
Run Code Online (Sandbox Code Playgroud)

Mal*_*wig 5

问题是您的自定义分区以不同于Guava的方法分配"空白空间"(即缺少元素留下的空隙以完全填充分区).该方法将在创建下一个分区之前完全填充每个分区,同时您希望均匀分布元素.这是因为您要partition()定义组的大小,而您要指定组的数量.

看看这个自定义实现:

private static <T> List<List<T>> distribute(List<T> elements, int nrOfGroups)
{
    int elementsPerGroup = elements.size() / nrOfGroups;
    int leftoverElements = elements.size() % nrOfGroups;

    List<List<T>> groups = new ArrayList<>();
    for (int i = 0; i < nrOfGroups; i++)
    {
        groups.add(elements.subList(i * elementsPerGroup + Math.min(i, leftoverElements),
                                    (i + 1) * elementsPerGroup + Math.min(i + 1, leftoverElements)));
    }
    return groups;
}
Run Code Online (Sandbox Code Playgroud)

它将计算出各组的最小尺寸(楼层数/#组),然后正确的,在情况下,第一几组有离开的元素.

例

List<Integer> elements = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8);
int nrOfGroups = 6;
// [[1, 2], [3, 4], [5], [6], [7], [8]]
Run Code Online (Sandbox Code Playgroud)