作为程序员每天除了写很多 if else
之外,写的最多的也包含 for
循环了,都知道我们 Java
中常用的 for
循环有两种方式,一种是使用 for loop
,另一种是使用 foreach
,那如果问你,这两种方式哪一种效率最高,你的回答是什么呢?今天阿粉就来带你看一下。
首先我们先通过代码来实际测试一下,在计算耗时之前我们先创建一个大小集合,然后通过不断的获取集合中的内容来测试耗时。
1 |
|
简单说明一下上面的带,先创建一个 List
,然后通过两种方式的遍历来计算耗时,根据集合的大小不同,我们进行运行会得到下面的一些测试数据,不同人的机器上面运行的时间会不一定,不过差距应该也不会太大。
size= | 10000 | 100000 | 1000000 | 10000000 |
---|---|---|---|---|
for loop | 1 | 2 | 10 | 12 |
for each | 1 | 3 | 17 | 34 |
通过上面的测试结果我们可以发现,在集合相对较小的情况下,for loop
和 foreach
两者的耗时基本上没有什么差别,当集合的数据量相对较大的时候,可以明显看的出来,for loop
的效率要比 foreach
的效率高。
至于为什么在大数据量的情况下 forEach
的效率要比 for
低,我们就要看下 forEach
的原理了。forEach
其实不是一种新的语法,而是一种 Java
的语法糖。在编译时,编译器会将这段代码转换成迭代器实现,并编译成字节码,我们可以再简单的看个 case
,来实际看下字节码信息。
我们再编写一个简单的类,代码如下
1 |
|
通过 ` javac ForEachTest.java ` 编译成 class 文件,再通过 javap -v ForEachTest
反编译,我们就会得到下面的字节码内容:
1 |
|
反编译的内容很多,不一一解释,可以看到这个字节码的一般含义是使用 getfield
命令获取变量,并调用 List.iterator
获取迭代器实例再调用 iterator.hasNext
,如果返回 true
,则调用 iterator.next
方法,这是迭代器遍历集合的实现逻辑。
写到这里有小伙伴就要问了,那以后遇到 List
集合我就用 for loop
了,不用 foreach
了,毕竟前者的效率更好。那么接下来我们再看一个 case
,这里我们把 ArrayList
换成 LinkedList
,代码如下:
1 |
|
size= | 1000 | 10000 | 100000 |
---|---|---|---|
for loop | 27 | 129 | 7654 |
For each | 2 | 2 | 15 |
从上面的数据可以很明显的看到,当在处理 LinkedList
的时候,for loop
明显就慢很多了。相信具体的原因大家也知道,ArrayList 底层是基于数组结构的,所以使用 for loop
操作起来会很快,时间复杂度是 O(1)
,但是 LinkedList
底层是链表结构,此时如果在想通过索引来操作数据,时间复杂度将是 O (n*n)
。
所以具体使用哪种循环方式以及具体需要使用哪种数据结构,都需要根据实际的业务情况来选择,任何一种方案的存在都是合理的,你小伙你们认为呢?欢迎在评论区留言讨论。