public static <IN, OUT> List<OUT> manyToOne(final List<IN> inputList, final int unitSize,
                                                final Function<List<IN>, OUT> func) {
        if (inputList == null || inputList.isEmpty()) {
            return Collections.emptyList();
        }

        final int inputSize = inputList.size();

        final List<OUT> outputList = Lists.newArrayListWithCapacity((int) Math.ceil((double) inputSize / unitSize));

        if (inputSize <= unitSize) {
            add(outputList, func.apply(inputList));
            return outputList;
        }

        List<IN> segment = Lists.newArrayListWithCapacity(unitSize);
        for (final IN input : inputList) {
            segment.add(input);
            if (segment.size() >= unitSize) {
                add(outputList, func.apply(segment));
                segment = Lists.newArrayListWithCapacity(unitSize);
            }
        }

        if (!segment.isEmpty()) {
            add(outputList, func.apply(segment));
        }

        return outputList;
    }
Batch tasks are split and executed in the smallest unit,
and the callback function (input -> output) is in a
many-to-one manner.

@param inputList input parameter list
@param unitSize  the minimum unit
@param func      the callback function
@param <IN>      input type
@param <OUT>     output type
jraft-rheakv/rheakv-core/src/main/java/com/alipay/sofa/jraft/rhea/util/Partitions.java