将List按照指定大小等分的几种实现方式和效率对比及优化
今天碰到一个需求,定时任务,批量从表里取数据并做一些其他操作然后再存表,每次取1000条,由于计算过程比较耗时所以要起多个线程同时跑,需要将List按照指定大小等分,如每100条数据起一个线程,若最后剩余一份不到100,也放到一个线程里,网络上的实现方法有很多,我测试之后理出三种相对比较好的实现方法,如下:
/*第一种方法 思路比较简单,遍历list,将元素添加到subList,
*每当i到pageSize的时候,将subList添加到listArray并新建,subList
*/
public static <T> List<List<T>> splitList1(List<T> list, int pageSize) { List<List<T>> listArray = new ArrayList<List<T>>(); List<T> subList = null; for (int i = 0; i < list.size(); i++) { if (i % pageSize == 0) { subList = new ArrayList<T>(); listArray.add(subList); } subList.add(list.get(i)); } return listArray; }
/*第二种方法 思路和方法1差不多,遍历list,将元素添加到subList,
*当subList的size等于pageSize的时候,将subList添加到listArray并新建subList
*/
public static <T> List<List<T>> splitList2(List<T> list, int pageSize) { List<List<T>> listArray = new ArrayList<List<T>>(); ArrayList<T> subList = new ArrayList<T>();
for (T x : list) {
subList.add(x);
if (pageSize == subList.size()) {
listArray.add(subList);
subList = new ArrayList<T>();
}
} if (0 != subList.size()) {
listArray.add(subList);
} return listArray;
}
/*第三种方法,用到了java list自带的方法subList,
*先判断list的size<pageSize的情况,然后利用subList方法循环切块
*/
public static <T> List<List<T>> splitList3(List<T> list, int pageSize) {
List<List<T>> listArray = new ArrayList<List<T>>();
if (list != null && pageSize > 0) {
int listSize = list.size();
if (listSize <= pageSize) {
listArray.add(list);
return listArray;
}
int batchSize = listSize / pageSize;
int remain = listSize % pageSize; for (int i = 0; i < batchSize; i++) {
int fromIndex = i * pageSize;
int toIndex = fromIndex + pageSize;
listArray.add(list.subList(fromIndex, toIndex));
}
if (remain > 0) {
listArray.add(list.subList(listSize - remain, listSize));
}
}
return listArray;
}
我从list的subList方法中得到灵感,也实现了一种方式,可读性稍好一些,如下:
/*我的思路也比较简单,就是遍历加切块,
*若toIndex大于list的size说明已越界,需要将toIndex设为list的size值
*/
public static <T> List<List<T>> splitList4(List<T> list, int pageSize) {
List<List<T>> listArray = new ArrayList<List<T>>();
for (int i = 0; i < list.size(); i+=pageSize) {
int toIndex = i + pageSize>list.size()?list.size():i+pageSize;
listArray.add(list.subList(i, toIndex));
}
return listArray;
}
以上四种方法经过测试都可实现功能,如果List的size比较小,几十,几百,应该效率都差不多,那如果list的size很大,比如10万,100万,那么以上四种方式,哪一种效率最高呢,我简单测试了一下,pageSize设为20,list的size分别为10万,和100万,分别跑100次,然后取平均值,如下:
public static void main(String[] args) {
ArrayList<Integer> list = new ArrayList<Integer>();
for (int i = 0; i < 100000; i++) {
list.add(i);
}
Long time1 = System.currentTimeMillis();
for (int i = 0; i <100 ; i++) {
splitList1(list, 20);
}
Long time2 = System.currentTimeMillis();
for (int i = 0; i <100 ; i++) {
splitList2(list, 20);
}
Long time3 = System.currentTimeMillis();
for (int i = 0; i <100 ; i++) {
splitList3(list, 20);
}
Long time4 = System.currentTimeMillis();
for (int i = 0; i <100 ; i++) {
splitList3(list, 20);
}
Long time5 = System.currentTimeMillis();
System.out.println("list的size为10000,执行100次,平均时间为:");
System.out.println("方法1--->:" + (time2 - time1)/100.0+"ms");
System.out.println("方法2--->:" + (time3 - time2)/100.0+"ms");
System.out.println("方法3--->:" + (time4 - time3)/100.0+"ms");
System.out.println("方法4--->:" + (time5 - time4)/100.0+"ms");
}
执行结果为:
list的size为100000,执行100次,平均时间为:
方法1--->:2.86ms
方法2--->:2.08ms
方法3--->:0.66ms
方法4--->:0.43ms
从执行结果中可以看到前两种方法效率,明显不如后两种,后两种时间相差不大,但看起来似乎方法4更好一些,再将list的size设为100万时,执行结果为:
list的size为1000000,执行100次,平均时间为:
方法1--->:21.65ms
方法2--->:14.09ms
方法3--->:0.95ms
方法4--->:0.57ms
size设为1000万时,执行结果为:
list的size为1000000,执行100次,平均时间为:
方法1--->:138.39ms
方法2--->:112.86ms
方法3--->:6.63ms
方法4--->:6.07ms
综上所看,方法4的效率稍好于方法3,方法2稍好于方法1,但3和4的效率比1和2要高出一个数量级,主要是因为方法1和2,是逐个设置的,很明显不如subList,在这里推荐方法4,代码简洁,稍微理解下,可读性也不错.
原文链接:https://www.imooc.com/article/41647
来源:慕课网
本文原创发布于慕课网 ,转载请注明出处,谢谢合作
将List按照指定大小等分的几种实现方式和效率对比及优化的更多相关文章
- 截取UIImage指定大小区域
截取UIImage指定大小区域 最近遇到这样的需求:从服务器获取到一张照片,只需要显示他的左半部分,或者中间部分等等.也就是截取UIImage指定大小区域. UIImage扩展 我的解决方案是对UII ...
- C# 图片超过指定大小将压缩到指定大小不失真
using System;using System.Collections.Generic;using System.Drawing;using System.Drawing.Drawing2D;us ...
- Linux下删除空文件,删除指定大小的文件
Linux下批量删除空文件(大小等于0的文件)的方法: find . -name "*" -type f -size 0c | xargs -n 1 rm -f 用这个还可以删除指 ...
- 2016-08-15:从YUV420P中提取指定大小区域
typedef struct { int width; int height; }SizeInfo; typedef struct { int x; int y; int width; int hei ...
- dd 生成指定大小文件
d命令可以轻易实现创建指定大小的文件,如 dd if=/dev/zero of=test bs=1M count=1000 会生成一个1000M的test文件,文件内容为全0(因从/dev/zero中 ...
- PHP 生成指定大小随机图片
PHP 生成指定大小随机图片 <?php $image_width = 100; $image_height = 100; $image_str = ''; if (isset($_GET['w ...
- PHP JS HTML ASP页面跳转代码 延时跳转代码 返回到上一界面并刷新 JS弹出指定大小的新窗口
1.PHP延时跳转代码 //跳转到浏览界面 header("Refresh:1;url=machine_list.php"); //不延时 <?php header(&quo ...
- linux dd命令参数及用法详解---用指定大小的块拷贝一个文件(也可整盘备份)
linux dd命令参数及用法详解---用指定大小的块拷贝一个文件 日期:2010-06-14 点击:3830 来源: 未知 分享至: linux dd命令使用详解 dd 的主要 ...
- Delphi中建立指定大小字体和读取该字体点阵信息的函数(转)
源:Delphi中建立指定大小字体和读取该字体点阵信息的函数 Delphi中建立指定大小字体和读取该字体点阵信息的函数 作者:Thermometer Email: webmaster@daheng- ...
随机推荐
- Zookeeper注册中心和Dubbo-Admin管理平台的搭建
ZooKeeper是一个分布式的,开放源码的分布式应用程序协调服务,是Google的Chubby一个开源的实现,是Hadoop和Hbase的重要组件.它是一个为分布式应用提供一致性服务的软件,提供的功 ...
- Linux系统命令行整理
1.pwd 查看当前所在目录 2.cd / 跳往根目录 3.ls 查看当前目录所有子目录或文件 4.ls -l 列出当前目录详细信息 5.ls -lh h=human 人性化列出当前目录详细 ...
- 第19章 定义资源 - Identity Server 4 中文文档(v1.0.0)
您通常在系统中定义的第一件事是您要保护的资源.这可能是您的用户的身份信息,如个人资料数据或电子邮件地址,或访问API. 注意 您可以使用C#对象模型定义资源 - 或从数据存储加载它们.IResourc ...
- VS项目发布到本地IIS
一.项目介绍 ①web项目,开发工具Visual Studio,语言C# ②本地IIS,手机上或其他用户在和本地在同一个局域网(并不绝对是指同一个WIFI)内访问,同时要把防火墙关掉 ③IIS全名In ...
- input框限制只能输入正整数、字母、小数、
这篇博文大部分来自于网上,为了方便自己查阅,以及帮助他人. 1,只能输入正整数 <input onkeyup="if(this.value.length==1){this.valu ...
- Array的 filter() 和 sort()
filter() filter() 方法创建一个创建一个新数组,新数组中的元素是通过筛选原数组中的元素所得到的.筛选的方式是把传入的函数依次作用于每个元素,然后根据返回值是true还是false决定保 ...
- Arcgis for Javascript 对接iServer发布的Mapserver服务
测试说明 webgis开发流程一般是: 数据处理 ---发布服务---SDK开发.除了开源的服务以外,一般各GIS厂商都是自己的服务自己的SDK才能对接. SuperMap iServer 提供了将 ...
- 关于ajax用户名验证和jquery实现简单表单验证
首先来说用户名验证: 前台: <tr> <td class="tableleft">教师编号</td> <td><input ...
- Spring Boot 相关
SpringBoot工程 参数解析 HTTP Method Request / Response / Session Error/重定向 Logger IoC AOP/Aspect 1:Sprin ...
- ASP.NET Core 入门教程 4、ASP.NET Core MVC控制器入门
一.前言 1.本教程主要内容 ASP.NET Core MVC控制器简介 ASP.NET Core MVC控制器操作简介 ASP.NET Core MVC控制器操作简介返回类型简介 ASP.NET C ...