1. 程式人生 > >[程式效率優化專題]1.for迴圈中的效率優化

[程式效率優化專題]1.for迴圈中的效率優化

在編碼中,我們像競技運動員一樣追求更快的速度。追求最優的演算法,看到一些同學的編碼質量停留著實現功能的層面,距離最優編碼相差很遠。所以一直想整理一下自己在實際專案遇到的問題和效率優化的文章和大家分享一下。本文是該系列文章的第一篇。for迴圈的效率優化。

1 for迴圈和增強for迴圈的選擇

jdk5.0加入了增強for迴圈,程式碼比普通for迴圈更加簡潔。

  • 普通for迴圈格式舉例
for(int i =0; i <1000000; i++){
    list.add(i);}
  • 增強for迴圈格式舉例
for(Integer i : list){int n = i;}

我們通過一個簡單的程式碼場景來比較一下普通for迴圈和增強for迴圈的效率。

1.1 實驗場景

初始化一個長度為1000000的ArrayList,分別通過for迴圈和增強for迴圈來遍歷,計算時間差。

示例程式碼:

package com.dashidan.profile;import java.util.ArrayList;/**
 * 大屎蛋教程網-dashidan.com
 * HashMap與ConcurrentHashMap的區別於應用場景
 * Created by 大屎蛋 on 2018/5/22.
 */publicclassDemo1{publicstaticvoid main(String[] args){/** 初始化陣列*/ArrayList<Integer> list 
=newArrayList<>();for(int i =0; i <1000000; i++){ list.add(i);}/** 普通for迴圈遍歷*/long t1 =System.currentTimeMillis();for(int i =0; i < list.size(); i++){int n = list.get(i);}/** 增強for迴圈遍歷*/long t2 =System.currentTimeMillis();for(Integer i : list){int n = i;}long t3 =System.currentTimeMillis
();System.out.println(t2 - t1);System.out.println(t3 - t2);}}

輸出

55

這個值根據電腦配置不同,輸出可能會有區別。多執行幾次,整體看來區別不大,所以這兩種for迴圈便利效率區別不大.增強for迴圈程式碼更加簡潔。對集合進行遍歷推薦採用增強for迴圈.

2 for迴圈遍歷HashMap的優化

for迴圈遍歷HashMap常用的有4種方式。

  • 通過hashMap.keySet()遍歷

keySet()方法返回HashMap中的key值的集合,然後通過get()方法傳入key值,可以得到key對應的value值。示例程式碼:

for(Integer key : hashMap.keySet()){intvalue= hashMap.get(key);}
  • 通過hashMap.values()遍歷

values()方法返回HashMap中的value值的集合。示例程式碼:

for(Integer v : hashMap.values()){intvalue= v;}
  • 通過hashMap.entrySet()遍歷 entrySet()方法返回HashMap中的key-value鍵值對集合。key和value一一對應,都可以獲取到。示例程式碼:
for(Map.Entry<Integer,Integer> entry : hashMap.entrySet()){int key = entry.getKey();intvalue= entry.getValue();}
  • 通過Iterator遍歷

以上3中遍歷方式都可以獲取結果集合的迭代器(Iterator),通過Iterator.next()方法遍歷結果集.示例程式碼:

Iterator<Integer> integerIterator = hashMap.values().iterator();while(integerIterator.hasNext()){intvalue= integerIterator.next();}

寫一個測試程式測試一下上述4中遍歷方式的效率.示例程式碼:

package com.dashidan.profile;import java.util.HashMap;import java.util.Iterator;import java.util.Map;/**
 * 大屎蛋教程網-dashidan.com
 * for迴圈中的效率優化
 * Created by 大屎蛋 on 2018/5/22.
 */publicclassDemo2{publicstaticvoid main(String[] args){int count =1000000;/** 初始化HashMap*/HashMap<Integer,Integer> hashMap =newHashMap<>();long t0 =System.currentTimeMillis();for(int i =0; i < count; i++){
            hashMap.put(i, i);}/** 遍歷Key獲取Value*/long t1 =System.currentTimeMillis();for(Integer key : hashMap.keySet()){intvalue= hashMap.get(key);}/** 遍歷value*/long t2 =System.currentTimeMillis();for(Integer v : hashMap.values()){intvalue= v;}long t3 =System.currentTimeMillis();/** 遍歷Entry*/for(Map.Entry<Integer,Integer> entry : hashMap.entrySet()){int key = entry.getKey();intvalue= entry.getValue();}long t4 =System.currentTimeMillis();/** Iterator 遍歷*/Iterator<Integer> integerIterator = hashMap.values().iterator();while(integerIterator.hasNext()){intvalue= integerIterator.next();}long t5 =System.currentTimeMillis();System.out.println(t1 - t0);System.out.println(t2 - t1);System.out.println(t3 - t2);System.out.println(t4 - t3);System.out.println(t5 - t4);}}

輸出結果

782110119

注意這個輸出結果,每次執行可能顯示不一致。總體說來,HashMap的put方法耗時會多餘get方法。通過遍歷keySet,然後再通過key獲取value的方式效率最低。其餘集中方式效率差不多。

結論:

  • 如果只需要遍歷value值,推薦採用遍歷values()集合的方式。
  • 如果遍歷hashmap時,key和value都需要用到,推薦採用遍歷entrySet的方式.