public static <T> List<List<T>> groupPartitions(List<T> elements, int numGroups) {
        if (numGroups <= 0)
            throw new IllegalArgumentException("Number of groups must be positive.");

        List<List<T>> result = new ArrayList<>(numGroups);

        // Each group has either n+1 or n raw partitions
        int perGroup = elements.size() / numGroups;
        int leftover = elements.size() - (numGroups * perGroup);

        int assigned = 0;
        for (int group = 0; group < numGroups; group++) {
            int numThisGroup = group < leftover ? perGroup + 1 : perGroup;
            List<T> groupList = new ArrayList<>(numThisGroup);
            for (int i = 0; i < numThisGroup; i++) {
                groupList.add(elements.get(assigned));
                assigned++;
            }
            result.add(groupList);
        }

        return result;
    }
Given a list of elements and a target number of groups, generates list of groups of
elements to match the target number of groups, spreading them evenly among the groups.
This generates groups with contiguous elements, which results in intuitive ordering if
your elements are also ordered (e.g. alphabetical lists of table names if you sort
table names alphabetically to generate the raw partitions) or can result in efficient
partitioning if elements are sorted according to some criteria that affects performance
(e.g. topic partitions with the same leader).

@param elements list of elements to partition
@param numGroups the number of output groups to generate.
connect/api/src/main/java/org/apache/kafka/connect/util/ConnectorUtils.java