解析Java?中for循環(huán)和foreach循環(huán)哪個更快
前言
在Java編程中,循環(huán)結(jié)構(gòu)是程序員常用的控制流程,而for循環(huán)和foreach循環(huán)是其中比較常見的兩種形式。關(guān)于它們哪一個更快的討論一直存在。本文旨在探究Java中的for循環(huán)和foreach循環(huán)的性能差異,并幫助讀者更好地選擇適合自身需求的循環(huán)方式。通過詳細(xì)比較它們的遍歷效率、數(shù)據(jù)結(jié)構(gòu)適用性和編譯器優(yōu)化等因素,我們將為大家揭示它們的差異和適用場景,以便您能夠做出更明智的編程決策。
for循環(huán)與foreach循環(huán)的比較
小編認(rèn)為for和foreach 之間唯一的實際區(qū)別是,對于可索引對象,我們無權(quán)訪問索引。
for(int i = 0; i < mylist.length; i++) { if(i < 5) { //do something } else { //do other stuff } }
但是,我們可以使用 foreach 創(chuàng)建一個單獨的索引 int 變量。例如:
int index = -1; for(int myint : mylist) { index++; if(index < 5) { //do something } else { //do other stuff } }
現(xiàn)在寫一個簡單的類,其中有 foreachTest() 方法,該方法使用 forEach 迭代列表。
import java.util.List; public class ForEachTest { List<Integer> intList; public void foreachTest(){ for(Integer i : intList){ } } }
編譯這個類時,編譯器會在內(nèi)部將這段代碼轉(zhuǎn)換為迭代器實現(xiàn)。小編通過執(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獲取迭代器實例
c).調(diào)用iterator.hasNext,如果返回true,則調(diào)用iterator.next方法。
下邊來做一下性能測試。在 IterateListTest 的主要方法中,創(chuàng)建了一個列表并使用 for 和 forEach 循環(huán)對其進(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比較它們的性能差異。對于 LinkedList 來說,for-each循環(huán)展現(xiàn)出更好的性能。ArrayList內(nèi)部使用連續(xù)存儲的數(shù)組,因此數(shù)據(jù)的檢索時間復(fù)雜度為 O(1),通過索引可以直接訪問數(shù)據(jù)。而 LinkedList 使用雙向鏈表結(jié)構(gòu),當(dāng)我們使用 for 循環(huán)進(jìn)行遍歷時,每次都需要從鏈表頭節(jié)點開始,導(dǎo)致時間復(fù)雜度達(dá)到了 O(n*n),因此在這種情況下,for-each 循環(huán)更適合操作 LinkedList。
以上就是解析Java 中for循環(huán)和foreach循環(huán)哪個更快的詳細(xì)內(nèi)容,更多關(guān)于Java for foreach循環(huán)的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Mybatis Plus 實現(xiàn)批量插入的示例代碼
本文主要介紹了Mybatis Plus 實現(xiàn)批量插入的示例代碼,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下2021-09-09SpringBoot響應(yīng)Json數(shù)據(jù)亂碼通過配置的解決
這篇文章主要介紹了SpringBoot響應(yīng)Json數(shù)據(jù)亂碼通過配置的解決,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-11-11Gitlab CI-CD自動化部署SpringBoot項目的方法步驟
本文主要記錄如何通過Gitlab CI/CD自動部署SpringBoot項目jar包。文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-07-07mybatisplus報Invalid bound statement (not found)錯誤的解決方法
搭建項目時使用了mybatisplus,項目能夠正常啟動,但在調(diào)用mapper方法查詢數(shù)據(jù)庫時報Invalid bound statement (not found)錯誤。本文給大家分享解決方案,感興趣的朋友跟隨小編一起看看吧2020-08-08Java8深入學(xué)習(xí)系列(三)你可能忽略了的新特性
一提到Java 8就只能聽到lambda,但這不過是其中的一個而已,Java 8還有許多新的特性,有一些功能強(qiáng)大的新類或者新的用法,還有一些功能則是早就應(yīng)該加到Java里了,所以下面這篇文章主要給大家介紹了關(guān)于Java8中大家可能忽略了的一些新特性,需要的朋友可以參考下。2017-08-08