内容来源于alibaba的开源项目ageiport,场景:如果需要基于集群节点进行均摊,对数据进行处理分而治之的话,就可以采用。
//均摊分配
public static <T> List<List<T>> averageAssign(List<T> source, int n) {
List<List<T>> result = new ArrayList<>();
//对当前的大小进行取模
int remaider = source.size() % n;
//对当前大小取整
int number = source.size() / n;
//偏移量
int offset = 0;
//对集群节点进行遍历
for (int i = 0; i < n; i++) {
List<T> value;
//如果模大于0,则对任务列表进行部分获取 List<E> subList(int fromIndex, int toIndex);
if (remaider > 0) {
value = source.subList(i * number + offset, (i + 1) * number + offset + 1);
remaider--;
offset++;
} else {
value = source.subList(i * number + offset, (i + 1) * number + offset);
}
result.add(value);
}
return result;
}
测试:
//测试均摊算法
public static void main(String[] args) {
//子任务列表
List<Integer> subTaskNos = new ArrayList<>();
subTaskNos.add(1);
subTaskNos.add(2);
subTaskNos.add(3);
subTaskNos.add(4);
subTaskNos.add(5);
subTaskNos.add(6);
subTaskNos.add(7);
subTaskNos.add(8);
subTaskNos.add(9);
subTaskNos.add(10);
subTaskNos.add(11);
subTaskNos.add(12);
//当前的集群节点
Integer nodeCount = 5;
//执行均摊
List<List<Integer>> subTaskAvgByNodeCount = Lists.averageAssign(subTaskNos, nodeCount);
System.out.println(subTaskAvgByNodeCount);
}
测试结果:
[1, 2, 3], [4, 5, 6], [7, 8], [9, 10], [11, 12]]
这个代码设计很巧妙,使用了取模和取余来实现对任务分发到不同的机器上,这样一来处理任务的时候,就可以快速完成任务的处理了。通常适应于大批量数据的处理。类似的思想:jdk中的fork-join也是分而治之的思想。