解析Java?中for循環(huán)和foreach循環(huán)哪個(gè)更快
前言
在Java編程中,循環(huán)結(jié)構(gòu)是程序員常用的控制流程,而for循環(huán)和foreach循環(huán)是其中比較常見(jiàn)的兩種形式。關(guān)于它們哪一個(gè)更快的討論一直存在。本文旨在探究Java中的for循環(huán)和foreach循環(huán)的性能差異,并幫助讀者更好地選擇適合自身需求的循環(huán)方式。通過(guò)詳細(xì)比較它們的遍歷效率、數(shù)據(jù)結(jié)構(gòu)適用性和編譯器優(yōu)化等因素,我們將為大家揭示它們的差異和適用場(chǎng)景,以便您能夠做出更明智的編程決策。

for循環(huán)與foreach循環(huán)的比較
小編認(rèn)為for和foreach 之間唯一的實(shí)際區(qū)別是,對(duì)于可索引對(duì)象,我們無(wú)權(quán)訪問(wèn)索引。
for(int i = 0; i < mylist.length; i++) {
if(i < 5) {
//do something
} else {
//do other stuff
}
}但是,我們可以使用 foreach 創(chuàng)建一個(gè)單獨(dú)的索引 int 變量。例如:
int index = -1;
for(int myint : mylist) {
index++;
if(index < 5) {
//do something
} else {
//do other stuff
}
}現(xiàn)在寫(xiě)一個(gè)簡(jiǎn)單的類,其中有 foreachTest() 方法,該方法使用 forEach 迭代列表。
import java.util.List;
public class ForEachTest {
List<Integer> intList;
public void foreachTest(){
for(Integer i : intList){
}
}
}編譯這個(gè)類時(shí),編譯器會(huì)在內(nèi)部將這段代碼轉(zhuǎn)換為迭代器實(shí)現(xiàn)。小編通過(guò)執(zhí)行 javap -verbose IterateListTest 反編譯代碼。
public void foreachTest();
descriptor: ()V
flags: ACC_PUBLIC
Code:
stack=1, locals=3, args_size=1
0: aload_0
1: getfield #19 // Field intList:Ljava/util/List;
4: invokeinterface #21, 1 // InterfaceMethod java/util/List.iterator:()Ljava/util/Iterator;
9: astore_2
10: goto 23
13: aload_2
14: invokeinterface #27, 1 // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
19: checkcast #33 // class java/lang/Integer
22: astore_1
23: aload_2
24: invokeinterface #35, 1 // InterfaceMethod java/util/Iterator.hasNext:()Z
29: ifne 13
32: return
LineNumberTable:
line 9: 0
line 12: 32
LocalVariableTable:
Start Length Slot Name Signature
0 33 0 this Lcom/greekykhs/springboot/ForEachTest;
StackMapTable: number_of_entries = 2
frame_type = 255 /* full_frame */
offset_delta = 13
locals = [ class com/greekykhs/springboot/ForEachTest, top, class java/util/Iterator ]
stack = []
frame_type = 9 /* same */從上面的字節(jié)碼我們可以看到:
a). getfield命令用于獲取變量整數(shù)。
b).調(diào)用List.iterator獲取迭代器實(shí)例
c).調(diào)用iterator.hasNext,如果返回true,則調(diào)用iterator.next方法。
下邊來(lái)做一下性能測(cè)試。在 IterateListTest 的主要方法中,創(chuàng)建了一個(gè)列表并使用 for 和 forEach 循環(huán)對(duì)其進(jìn)行迭代。
import java.util.ArrayList;
import java.util.List;
public class IterateListTest {
public static void main(String[] args) {
List<Integer> mylist = new ArrayList<>();
for (int i = 0; i < 1000000; i++) {
mylist.add(i);
}
long forLoopStartTime = System.currentTimeMillis();
for (int i = 0; i < mylist.size(); i++) {mylist.get(i);}
long forLoopTraversalCost =System.currentTimeMillis()-forLoopStartTime;
System.out.println("for loop traversal cost for ArrayList= "+ forLoopTraversalCost);
long forEachStartTime = System.currentTimeMillis();
for (Integer integer : mylist) {}
long forEachTraversalCost =System.currentTimeMillis()-forEachStartTime;
System.out.println("foreach traversal cost for ArrayList= "+ forEachTraversalCost);
}
}結(jié)果如下:

總結(jié)
觀察結(jié)果顯示,for循環(huán)的性能優(yōu)于for-each循環(huán)。然后再使用LinkedList比較它們的性能差異。對(duì)于 LinkedList 來(lái)說(shuō),for-each循環(huán)展現(xiàn)出更好的性能。ArrayList內(nèi)部使用連續(xù)存儲(chǔ)的數(shù)組,因此數(shù)據(jù)的檢索時(shí)間復(fù)雜度為 O(1),通過(guò)索引可以直接訪問(wèn)數(shù)據(jù)。而 LinkedList 使用雙向鏈表結(jié)構(gòu),當(dāng)我們使用 for 循環(huán)進(jìn)行遍歷時(shí),每次都需要從鏈表頭節(jié)點(diǎn)開(kāi)始,導(dǎo)致時(shí)間復(fù)雜度達(dá)到了 O(n*n),因此在這種情況下,for-each 循環(huán)更適合操作 LinkedList。
以上就是解析Java 中for循環(huán)和foreach循環(huán)哪個(gè)更快的詳細(xì)內(nèi)容,更多關(guān)于Java for foreach循環(huán)的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Spring中Bean創(chuàng)建完后打印語(yǔ)句的兩種方法
這篇文章主要介紹了Spring中Bean創(chuàng)建完后打印語(yǔ)句的兩種方法,一個(gè)是實(shí)現(xiàn)InitializingBean接口,另一個(gè)使用@Bean注解和initMethod屬性,通過(guò)代碼示例介紹的非常詳細(xì),感興趣的小伙伴可以參考閱讀2023-07-07
Java?synchornized與ReentrantLock處理并發(fā)出現(xiàn)的錯(cuò)誤
synchronized機(jī)制提供了對(duì)每個(gè)對(duì)象相關(guān)的隱式監(jiān)視器鎖,并強(qiáng)制所有鎖的獲取和釋放都必須在同一個(gè)塊結(jié)構(gòu)中。當(dāng)獲取了多個(gè)鎖時(shí),必須以相反的順序釋放。即synchronized對(duì)于鎖的釋放是隱式的2023-01-01
Java事件處理機(jī)制(自定義事件)實(shí)例詳解
這篇文章主要介紹了Java事件處理機(jī)制(自定義事件)實(shí)例詳解的相關(guān)資料,需要的朋友可以參考下2016-12-12
SpringBoot之@Controller和@RequestMapping的實(shí)現(xiàn)原理解讀
這篇文章主要介紹了SpringBoot之@Controller和@RequestMapping的實(shí)現(xiàn)原理,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2025-04-04
使用IDEA配置Maven搭建開(kāi)發(fā)框架ssm教程
這篇文章主要為大家詳細(xì)介紹了使用IDEA配置Maven搭建開(kāi)發(fā)框架ssm教程,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-07-07
IntelliJ IDEA中打開(kāi)拼寫(xiě)檢查與忽略提示曲線的方法
今天小編就為大家分享一篇關(guān)于IntelliJ IDEA中打開(kāi)拼寫(xiě)檢查與忽略提示曲線的方法,小編覺(jué)得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧2018-10-10
Java中Cookie和Session詳解及區(qū)別總結(jié)
這篇文章主要介紹了Java中Cookie和Session詳解,文章圍繞主題展開(kāi)詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,感興趣的小伙伴可以參考一下2022-06-06
設(shè)計(jì)模式之模版方法模式_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理
這篇文章主要介紹了設(shè)計(jì)模式之模版方法模式,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-08-08
ConcurrentHashMap線程安全及實(shí)現(xiàn)原理實(shí)例解析
這篇文章主要介紹了ConcurrentHashMap線程安全及實(shí)現(xiàn)原理實(shí)例解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-11-11

