求:如何快速遍历几个list取得所有组合

Jobernowl 2011-06-16 10:29:44
我有五个list要循环每个list大约存有20个左右的对象(不相等 并且大小根据参数会不一样) 比如
List<EquipArm> armList;
List<EquipBody> bodyList;
List<EquipHead> headList;
List<EquipLeg> legList;
List<EquipWst> wstList;


然后我在下面遍历循环 List<Equipment> equipmentList=new ArrayList<Equipment>();
for(int a=0;a<armList.size();a++)
for(int b=0;b<bodyList.size();b++)
for(int c=0;c<headList.size();c++)
for(int d=0;d<legList.size();d++)
for(int e=0;e<wstList.size();e++)
{
Equipment equipment=new Equipment();
equipment.setEquipArm(armList.get(a));
equipment.setEquipBody(bodyList.get(b));
equipment.setEquipHead(headList.get(c));
equipment.setEquipLeg(legList.get(d));
equipment.setEquipWst(wstList.get(e));
equipmentList.add(equipment);
}

然后就是运行的时候每次都要等2分钟左右才出结果 跪求如何快速遍历循环取得所有组合 或者有新的方法请告诉我
...全文
971 27 打赏 收藏 转发到动态 举报
写回复
用AI写文章
27 条回复
切换为时间正序
请发表友善的回复…
发表回复
Jobernowl 2011-06-18
  • 打赏
  • 举报
回复
有谁想看我的代码 和我到底做的是哪个程序么 想的就把联系方式告诉我 我发过去 希望能等到大家的帮助
Jobernowl 2011-06-18
  • 打赏
  • 举报
回复
有一个程序 我不知道他怎么在一瞬间获得那个范围 想不明白啊 也许他在开始的时候压根没用到集合
Jobernowl 2011-06-18
  • 打赏
  • 举报
回复
[Quote=引用 17 楼 shine333 的回复:]
初始化ArrayList的时候,指定大小。

Java code

List<Equipment> equipmentList=new ArrayList<Equipment>(armList.size()*bodyList.size()*....);

默认大小只有10,然后不够的时候,每次变大50%+1,然后再把原来的内容,复制到新的地方去。相对来说,复制很花费时间。你默认10,变……
[/Quote]感谢大神指教 我的程序确实想获得很多集合 然后再在这个集合里面进一步挑选
qybao 2011-06-17
  • 打赏
  • 举报
回复
改成一个循环试试看

int[] size = {wstList.size(),legList.size(), headList.size(), 
bodyList.size(), armList.size()};
int[] loop = new int[size.length];
loop[0] = size[0];
for (int i=1; i<size.length; i++) {
loop[i] = loop[i-1]*size[i];
}
for (int i=0; i<loop[4]; i++) {
Equipment equipment=new Equipment();
equipment.setEquipArm(armList.get((i/loop[3])%size[4]));
equipment.setEquipBody(bodyList.get((i/loop[2])%size[3]));
equipment.setEquipHead(headList.get((i/loop[1])%size[2]));
equipment.setEquipLeg(legList.get((i/loop[0])%size[1]));
equipment.setEquipWst(wstList.get(i%size[0]));
equipmentList.add(equipment);
}
Jobernowl 2011-06-17
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 renhuihhh 的回复:]
用多线程 那才叫快呐!
[/Quote]

能不能用代码表示呢 几个for嵌套能分开同时处理?
Jobernowl 2011-06-17
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 mywayhome 的回复:]
分开循环遍历就可以了
像LZ写的这样,for循环嵌套for循环,最终循环次数在20*20*20*20*20,数量如此庞大当然慢了
如果分开的话,是20*5,只要100次,这就快了
[/Quote]
听上去好像很厉害 能不能用代码表示出来呢 我是新手 脑子有些笨
Jobernowl 2011-06-17
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 fly_m 的回复:]
没办法,你这里面的运行就有这么多次。6个循环就是 20 * 20 * 20 * 20 * 20 * 20=640000次循环。加上中间处理。肯定慢了。

不过你这个可以优化下。在每个循环开始时,先取出当前的临时对象,避免在最里面中再取一次。
TempA at;
TempB bt;
TempC ct;
TempD dt;
TempE et;

Java code

for(in……
[/Quote]感谢大神 等去学校试试
qybao 2011-06-17
  • 打赏
  • 举报
回复
首先,看LZ代码的本意,要生成20*20*20*20*20个Equipment对象,拆开循环,就不是这个数量了。
其次,如果LZ的list如果是ArrayList,那么和数组差不多
单纯的0到20*20*20*20*20循环,本身也要花一定时间的,所以象LZ这样的嵌套循环,只能尽量改善,就是把数量小的循环放在外层,数量大的循环放在里层。

for (int i=0; i<10; i++) {
for (int j=0; j<100; j++) {

}
}
这样的嵌套要比
for (int i=0; i<100; i++) {
for (int j=0; j<10; j++) {

}
}
性能好
另外,如果循环比较大,象i,j这样的循环变量,可以放在循环外定义,不要每次都在循环内定义

int i,j;
for (i=0; i<10; i++) P
for (j=0; j<100; j++) {

}
}
飞跃颠峰 2011-06-17
  • 打赏
  • 举报
回复
抱歉,上面写错了一点点,

if (eqs.size()<i) 得改成
if (eqs.size()<=i)
飞跃颠峰 2011-06-17
  • 打赏
  • 举报
回复
楼主你这嵌套循环,次数几何级数增长,那当然慢了。必须把循环拆解开来。而且由于5个List的长度未必相同,在添加之前判断一下是否需要自动创建新Equipment。


List<Equipment> eqs = new ArrayList<Equipment>();
int i;
for (i=0; i<armList.size; i++) {
if (eqs.size()<i) eqs.add(new Equipment());
eqs.get(i).setEquipArm(armList.get(i));
}
for (i=0; i<bodyList.size; i++) {
if (eqs.size()<i) eqs.add(new Equipment());
eqs.get(i).setEquipBody(bodyList.get(i));
}
for (i=0; i<headList.size; i++) {
if (eqs.size()<i) eqs.add(new Equipment());
eqs.get(i).setEquipHead(headList.get(i));
}
for (i=0; i<legList.size; i++) {
if (eqs.size()<i) eqs.add(new Equipment());
eqs.get(i).setEquipLeg(legList.get(i));
}
for (i=0; i<wstList.size; i++) {
if (eqs.size()<i) eqs.add(new Equipment());
eqs.get(i).setEquipWst(wstList.get(i));
}

Jobernowl 2011-06-17
  • 打赏
  • 举报
回复
那么能不能生成一个个数组 然后再根据数组来添加呢 感觉生成数字好像有更快的方法 再者直接取进集合也比较快吧
riyuezhizhi 2011-06-17
  • 打赏
  • 举报
回复
同意阿宝的观点,这种情况下多线程要比单线程耗时更多。
bayougeng 2011-06-17
  • 打赏
  • 举报
回复
我的想法是,在循环中只把索引存起来,然后用到的时候再去根据索引做set。
比如你要用到equipment的时候,取出的索引是:00000,然后:
Equipment equipment=new Equipment();
equipment.setEquipArm(armList.get(0));
equipment.setEquipBody(bodyList.get(0));
equipment.setEquipHead(headList.get(0));
equipment.setEquipLeg(legList.get(0));
equipment.setEquipWst((0));

bayougeng 2011-06-17
  • 打赏
  • 举报
回复
好像怎么改意义都不大。毕竟有这么多种排列组合。
飞跃颠峰 2011-06-17
  • 打赏
  • 举报
回复
楼主我给你提供另外一个思路,但只适合特别场合。

改写Equipment类,里面包含5个静态数组,
此外再定义一个id,根据id可以唯一推导出5个下标

这样你的遍历就可以这样写了:

int length = l1.size()*l2.size()*l3.size()*l4.size()*l5.size();
Equitment.setLists(l1,l2,l3,l4,l5);
ArrayList<Equipment> eqs = new ArrayList<Equipment>();
for (int id=0; id<length; id++)
eqs.add(new Equipment(id));

循环的次数没减少,但赋值的开销小多了。
qybao 2011-06-17
  • 打赏
  • 举报
回复
对于单CPU,多线程是不会提高速度的,因为多线程是轮流是用CPU,实际上等效于单线程,也就是单线程处理所需的CPU时间和多线程处理所需的CPU时间的总和几乎是一样(在这种情况下,单线程实际上比多线程速度快,因为不用切换线程影响CPU时间)
多线程的用途不在这里,多线程是为了协调并发处理的响应阻塞问题,也就是并发处理的时候,说某个处理不需要等待另一个处理结束才能执行。但这不是为了加速程序运行,而是分散程序运行,最终分散处理的总时间实际上和单线程处理的总时间是差不多的。
飞跃颠峰 2011-06-17
  • 打赏
  • 举报
回复
哦,真不好意思,我看错楼主的本意了。
BearKin 2011-06-17
  • 打赏
  • 举报
回复
[Quote=引用楼主 sasuke38 的回复:]
我有五个list要循环每个list大约存有20个左右的对象(不相等 并且大小根据参数会不一样) 比如
List<EquipArm> armList;
List<EquipBody> bodyList;
List<EquipHead> headList;
List<EquipLeg> legList;
List<EquipWst> wstList;


然后我在……
[/Quote]

我换个角度咨询LZ点事情:LZ认为你现在的写法得到的结果是你需要的么?如果是你需要的话 那没什么好说的了 这个流程是必须要走的 就无可避免
shine333 2011-06-17
  • 打赏
  • 举报
回复
说错了,是扩容30次,第1个容量是10,第31个容量是3392918.
shine333 2011-06-17
  • 打赏
  • 举报
回复
初始化ArrayList的时候,指定大小。

List<Equipment> equipmentList=new ArrayList<Equipment>(armList.size()*bodyList.size()*....);

默认大小只有10,然后不够的时候,每次变大50%+1,然后再把原来的内容,复制到新的地方去。相对来说,复制很花费时间。你默认10,变到能够放下20 * 20 * 20 * 20 * 20 = 3200000,需要扩容31次,也就是第一次复制之前10个,第二次复制16个,25个,.....第28次1005308,1507963,2261945,第31次3392918。代价太大了。

另外,这是你的完整代码,循环中间没有别的操作了??
加载更多回复(5)

50,523

社区成员

发帖
与我相关
我的任务
社区描述
Java相关技术讨论
javaspring bootspring cloud 技术论坛(原bbs)
社区管理员
  • Java相关社区
  • 小虚竹
  • 谙忆
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧