整合營銷服務(wù)商

          電腦端+手機(jī)端+微信端=數(shù)據(jù)同步管理

          免費(fèi)咨詢熱線:

          java遍歷List的三種方式比較 用數(shù)據(jù)說明為什么

          java遍歷List的三種方式比較 用數(shù)據(jù)說明為什么推薦使用foreach

          考鏈接:

          http://www.trinea.cn/android/arraylist-linkedlist-loop-performance/

          https://docs.oracle.com/javase/specs/jls/se7/html/jls-14.html#jls-14.14.2

          foreach也稱為增強(qiáng)for循環(huán),是java5新特性,可用于遍歷數(shù)組或?qū)崿F(xiàn)了Iterable接口的集合容器。

          1.遍歷List的方式:

          假設(shè)已有數(shù)據(jù):

          List<Integer> list;

          (1) foreach循環(huán):

          for (Integer j : list) {

          // use j

          }

          (2) 下標(biāo)遞增(遞減)循環(huán):

          int size=list.size();

          for (int j=0; j < size; j++) {

          list.get(j);

          }

          (3) 迭代器循環(huán)迭代:

          for (Iterator<Integer> iterator=list.iterator(); iterator.hasNext();) {

          iterator.next();

          }

          2.三種遍歷方式的性能比對(duì)

          經(jīng)測(cè)試通過上述三種方式分別迭代ArrayList和LinkedList時(shí)所消耗的時(shí)間如下:

          compare loop performance of ArrayList

          -----------------------------------------------------------------------

          list size | 10,000 | 100,000 | 1,000,000 | 10,000,000

          -----------------------------------------------------------------------

          for each | 1 ms | 3 ms | 14 ms | 152 ms

          -----------------------------------------------------------------------

          for iterator | 0 ms | 1 ms | 12 ms | 114 ms

          -----------------------------------------------------------------------

          for size=list.size() | 0 ms | 0 ms | 6 ms | 62 ms

          -----------------------------------------------------------------------

          compare loop performance of LinkedList

          -----------------------------------------------------------------------

          list size | 100 | 1,000 | 10,000 | 100,000

          -----------------------------------------------------------------------

          for each | 0 ms | 1 ms | 1 ms | 2 ms

          -----------------------------------------------------------------------

          for iterator | 0 ms | 0 ms | 0 ms | 2 ms

          -----------------------------------------------------------------------

          for size=list.size() | 0 ms | 0 ms | 67 ms | 8216 ms

          3.List遍歷方式及其性能表現(xiàn)分析:

          ArrayList:

          當(dāng)size < 100萬時(shí),三種方式性能差別不大;

          當(dāng)size >=100萬時(shí),for > iterator >=foreach.

          LinkedList:

          當(dāng)size小于1萬時(shí),三種方式性能差別不大;

          當(dāng)size>=1萬時(shí), iterator >=foreach > for.

          由于foreach底層也是通過iterator來迭代,因此foreach的性能與iterator接近。

          是什么影響了這三種遍歷方式的性能呢?

          主要原因是List的底層數(shù)據(jù)結(jié)構(gòu)和從List容器中獲取元素的算法。

          我們知道ArrayList的底層數(shù)據(jù)結(jié)構(gòu)是數(shù)組,LinkedList是鏈表。

          這三種遍歷方式從List中獲取元素的算法分別為:

          1) foreach循環(huán)和iterator迭代器:

          都是調(diào)用iterator.next(),查看ArrayList對(duì)于iterator中next方法的實(shí)現(xiàn)可知其最終是通過數(shù)組下標(biāo)獲取元素。如下圖:

          ArrayList迭代之next

          查看LinkedList對(duì)于iterator中next方法的實(shí)現(xiàn)可知其最終是調(diào)用了父類AbstractList中iterator的實(shí)現(xiàn),然后調(diào)用了get(index),而LinkedList的get方法是通過遍歷鏈表來獲取元素的。如下圖:

          2) for循環(huán):調(diào)用get(index).

          綜上,這三種遍歷方式從容器中獲取元素的方式如下圖:

          可見遍歷ArrayList時(shí)最終都是直接通過數(shù)組下標(biāo)定位元素的,這應(yīng)該是當(dāng)ArrayList的容量在100萬以內(nèi)時(shí),其遍歷時(shí)間在20ms以內(nèi)的根本原因。

          遍歷LinkedList時(shí)最終都是查詢鏈表。但為什么iterator方式遍歷LinkedList的速度是for的數(shù)千倍呢?因?yàn)閕terator利用了游標(biāo),而后者是調(diào)用了get(index)方法將鏈表從頭到尾或從尾到頭查了一遍。

          4.為什么推薦使用foreach

          最后我們來看一下為什么諸如《Effective-Java》都推薦使用foreach:

          1) 性能較優(yōu):

          分析上文性能測(cè)試結(jié)果發(fā)現(xiàn),通過foreach遍歷ArrayList時(shí)當(dāng)size < 100萬時(shí),時(shí)間在20ms以內(nèi),并不比for循環(huán)差多少。遍歷size在百萬以上的超大ArrayList的時(shí)其性能明顯低于for循環(huán)遍歷方式。

          通過foreach遍歷LinkedList時(shí),無論size大小,其性能始終接近于最優(yōu)的iterator遍歷方式。

          2) 書寫簡(jiǎn)潔。

          3) 不必關(guān)心元素下標(biāo),可避免數(shù)組下標(biāo)越界。

          最后別忘了點(diǎn)波關(guān)注哦!

          JavaScript作為Web前端開發(fā)的基石,其強(qiáng)大的功能和靈活性不僅體現(xiàn)在網(wǎng)頁的動(dòng)態(tài)交互上,更在于其處理數(shù)據(jù)的能力。數(shù)組遍歷是JavaScript中最常見的操作之一,尤其在算法題的求解過程中,它扮演著至關(guān)重要的角色。本文將深入探討JavaScript中數(shù)組遍歷的多種方法,通過具體的算法題示例,幫助讀者掌握高效解決問題的技巧。


          技術(shù)概述

          數(shù)組遍歷方法

          在JavaScript中,數(shù)組遍歷可以通過多種方式進(jìn)行,每種方法都有其特點(diǎn)和適用場(chǎng)景:

          • for循環(huán):最傳統(tǒng)的遍歷方式,適用于所有情況。
          • forEach():ES5引入的數(shù)組方法,簡(jiǎn)化了遍歷語法。
          • map():用于創(chuàng)建新數(shù)組,對(duì)原數(shù)組的每個(gè)元素進(jìn)行映射操作。
          • filter():用于篩選數(shù)組,返回滿足條件的元素組成的新數(shù)組。
          • reduce():用于對(duì)數(shù)組元素進(jìn)行累積操作,常用于求和、合并等場(chǎng)景。
          • some()every():用于檢查數(shù)組中是否存在滿足條件的元素或所有元素是否都滿足條件。

          代碼示例

          const numbers=[1, 2, 3, 4, 5];
          
          // 使用for循環(huán)遍歷
          for (let i=0; i < numbers.length; i++) {
              console.log(numbers[i]);
          }
          
          // 使用forEach遍歷
          numbers.forEach(number=> console.log(number));
          
          // 使用map創(chuàng)建新數(shù)組
          const doubled=numbers.map(number=> number * 2);
          console.log(doubled); // 輸出: [2, 4, 6, 8, 10]
          

          技術(shù)細(xì)節(jié)

          工作原理

          數(shù)組遍歷方法本質(zhì)上是通過迭代數(shù)組中的每一個(gè)元素來執(zhí)行特定的邏輯操作。不同的方法提供不同的操作能力,如map用于變換,filter用于篩選,而reduce用于聚合。

          難點(diǎn)分析

          • 性能考量:盡管現(xiàn)代JavaScript引擎進(jìn)行了大量的優(yōu)化,但在處理大規(guī)模數(shù)據(jù)時(shí),遍歷方法的選擇仍然會(huì)影響性能。
          • 副作用管理:在遍歷時(shí)避免對(duì)原始數(shù)組造成不必要的修改,尤其是使用mapfilter時(shí)。

          實(shí)戰(zhàn)應(yīng)用

          應(yīng)用場(chǎng)景

          假設(shè)我們有一道算法題,要求找出數(shù)組中所有偶數(shù),并返回它們的平方和。

          代碼示例

          function sumOfSquaresEvenNumbers(numbers) {
              return numbers
                  .filter(number=> number % 2===0) // 篩選偶數(shù)
                  .map(number=> number * number)     // 平方
                  .reduce((acc, curr)=> acc + curr, 0); // 求和
          }
          
          const result=sumOfSquaresEvenNumbers([1, 2, 3, 4, 5, 6]);
          console.log(result); // 輸出: 56
          

          優(yōu)化與改進(jìn)

          潛在問題

          • 性能瓶頸:對(duì)于大數(shù)據(jù)集,多次迭代可能會(huì)導(dǎo)致性能下降。
          • 代碼冗余:過度使用高階函數(shù)可能導(dǎo)致代碼不易理解。

          代碼示例

          function optimizedSumOfSquaresEvenNumbers(numbers) {
              let sum=0;
              for (let number of numbers) {
                  if (number % 2===0) {
                      sum +=number * number;
                  }
              }
              return sum;
          }
          
          const optimizedResult=optimizedSumOfSquaresEvenNumbers([1, 2, 3, 4, 5, 6]);
          console.log(optimizedResult); // 輸出: 56
          

          常見問題

          • Q: 如何在遍歷數(shù)組時(shí)避免修改原數(shù)組?
          • A: 使用mapfilter等方法,它們會(huì)返回新數(shù)組,而不會(huì)修改原數(shù)組。

          總結(jié)與展望

          數(shù)組遍歷不僅是JavaScript編程的基礎(chǔ),也是解決復(fù)雜算法問題的利器。通過本文的探討,我們不僅學(xué)習(xí)了多種數(shù)組遍歷的方法,還掌握了如何在實(shí)際問題中選擇合適的遍歷策略,以提高代碼的效率和可讀性。未來,隨著JavaScript語言的不斷發(fā)展,新的數(shù)組方法和迭代器模式將進(jìn)一步豐富我們的編程工具箱,為開發(fā)者提供更加高效和靈活的解決方案。掌握數(shù)組遍歷的技巧,意味著在算法題的求解中擁有了更多的選擇和自信,這也是前端開發(fā)者邁向更高層次的關(guān)鍵一步。

          ava中的foreach循環(huán)的用法


          主站蜘蛛池模板: 亚洲综合av一区二区三区不卡| 亚洲色精品VR一区区三区| 精品乱人伦一区二区三区| 中文字幕一区日韩在线视频| 日韩亚洲AV无码一区二区不卡| 亚洲一区二区三区高清视频| 国产精品综合一区二区三区| 国精品无码一区二区三区左线| 色一情一乱一伦一区二区三欧美| 一区二区在线视频免费观看| 伊人久久大香线蕉AV一区二区| 亚洲国产高清在线一区二区三区| 国产亚洲一区区二区在线| 人妻无码第一区二区三区| 亚洲日韩激情无码一区| 天堂不卡一区二区视频在线观看| 麻豆一区二区99久久久久| 亲子乱AV视频一区二区| 国产福利一区二区在线视频| 亚洲国产成人久久一区二区三区| 人妻AV一区二区三区精品| 国模少妇一区二区三区| 国产精品无码一区二区三区电影| 波霸影院一区二区| AV无码精品一区二区三区宅噜噜| 国模吧一区二区三区精品视频| 国产品无码一区二区三区在线| 亚洲熟妇成人精品一区| 国产一区二区成人| 在线观看精品视频一区二区三区 | 无码少妇A片一区二区三区| 中文字幕精品一区二区日本| 精品女同一区二区三区免费站 | 人妻夜夜爽天天爽爽一区| 麻豆一区二区99久久久久| 亚洲精品无码一区二区| 一区二区三区视频免费| 无码国产精品一区二区免费模式 | 亚洲欧美国产国产综合一区| 亚洲欧洲一区二区三区| 无码中文字幕一区二区三区|