前几天有人问过我一个问题,就是两个嵌套for循环执行效率的问题,问有什么好的办法替换。当时我想了想,实在想不起来,哎,惭愧!!! 请教了答案,恍然大悟。
比如:两个list中分别装有相同的对象数据。 list1中有3万条对象数据。 list2中有2万条对象数据(但是对象中的某个属性变量为空)。两个list中的id或者其他变量都一模一样。请用最快的方式找出list2中变量为空的那个对象,并且去list1中找出id相同的对象。 或者可以理解成,从list2中找出变量为空的,去list1中找出对应的对象,然后把为空的列补上。总之就是这么一个意思,先 for 循环 list2,判断一下每个对象的那个属性变量是否为空,如果为空,再去for循环list1,找出id一样的对象,就算执行成功了。
那么请看下边的for循环嵌套的解决方式:
1
2
3
4
5
6
7
8
9
|
for (Member m2:list2){
if (m2.getName()== null ){
for (Member m1:list1){
if (m1.getId().intValue()==m2.getId().intValue()){
System.out.println(m2.getId()+ " Name 值为空!!!" );
}
}
}
}
|
这样真的好吗? 如果有上万,甚至十几万的数据,那么这个执行效率问题,我就不多说了。 非常非常的慢。
下边来看使用map代替的执行方式,以及两种方式的效率对比:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
|
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
class Member {
private Integer id;
private String name;
private Integer age;
private Date addDate;
public Member() {
}
public Member(Integer id, String name, Integer age, Date addDate) {
super ();
this .id = id;
this .name = name;
this .age = age;
this .addDate = addDate;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this .id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this .name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this .age = age;
}
public Date getAddDate() {
return addDate;
}
public void setAddDate(Date addDate) {
this .addDate = addDate;
}
}
public class For2 {
public static void main(String[] args) throws InterruptedException {
List<Member> list1 = new ArrayList<>();
List<Member> list2 = new ArrayList<>();
for ( int i= 0 ;i< 30000 ;i++){
Date date = new Date();
list1.add( new Member((i+ 1 ), "技术客" ,(i+ 1 ), date));
if (i% 2 == 0 ){
list2.add( new Member((i+ 1 ), null ,(i+ 1 ), date));
}
}
//双for循环嵌套测试
long s1 = System.currentTimeMillis();
int forNumber = 0 ;
for (Member m2:list2){
if (m2.getName()== null ){
for (Member m1:list1){
if (m1.getId().intValue()==m2.getId().intValue()){
// System.out.println(m2.getId()+" Name 值为空!!!");
forNumber++;
}
}
}
}
long s2 = System.currentTimeMillis();
System.out.println( "双for循环查询时间为:" +(s2-s1)+ "(毫秒),一共查询出" +forNumber+ "条数据 \n\n\n" );
TimeUnit.SECONDS.sleep( 3 );
//map查询测试
long s3 = System.currentTimeMillis();
int mapNumber = 0 ;
Map<Integer, Member> map = new HashMap<>();
for (Member m1:list1){
map.put(m1.getId(), m1);
}
for (Member m2:list2){
if (m2.getName()== null ){
Member m = map.get(m2.getId());
if (m!= null ){
// System.out.println(m2.getId()+" Name 值为空!!!");
mapNumber++;
}
}
}
long s4 = System.currentTimeMillis();
System.out.println( "使用map结构查询时间为:" +(s4-s3)+ "(毫秒),一共查询出" +mapNumber+ "条数据 \n\n\n" );
}
}
|
输出结果:
双for循环查询时间为:1578(毫秒),一共查询出15000条数据
使用map结构查询时间为:14(毫秒),一共查询出15000条数据
如果我们模拟10万条数据,然后其中五千条重复数据的情况下:效率更是天壤之别。
看输出结果:
双for循环查询时间为:30929(毫秒),一共查询出50000条数据
使用map结构查询时间为:24(毫秒),一共查询出50000条数据
循环数据越小,两者差别也就越小,但是数据量越大,差别也就越大。 10万条数据的差别竟然达到上千倍!
以上就是Java优化for循环嵌套的高效率方法的详细内容,更多关于Java 优化 for循环的资料请关注服务器之家其它相关文章!
原文链接:https://www.sunjs.com/article/detail/2932f6f6d7aa4da089dcf558f0629d97.html