由遍歷集合所聯想到的一些問題

2022-08-27 06:12:11 字數 2266 閱讀 9295

1、以下一段再平常不過的遍歷**,但是與我一樣,好多新手都會在這個地方出問題,例如

for(int i=0; i)

// 執行;

之前我在剛工作的時候在這個地方犯錯,我們在自測的時候都沒問題。初始化資料之後給客戶演示時,突然蹦出個空指標異常nullpointerexception。

於是我們通過debug發現,這個list為空,平常我們開發都會手工插入一些資料到表,自然不會報空,演示的時候資料表為空,自然就報錯了。

改進:

for(int i=0; list!=null&&i)

//執行;

不會報錯了吧!

但是有經驗的開發人員會發現for迴圈,每次都會去對迴圈條件進行判斷,於是繼續改進

if(list!=null && !list.isempty())

for(int i=0; i)

//執行;

還有問題嗎

我們會發現迴圈還是每次都會去執行list.size();方法,list.size()方法也就是一句**return size;看似簡單的一句**,但是我們知道每次執行乙個方法jvm都會為該方法申請乙個棧幀,過程雖短,但是也是一項不小的開銷。

於是繼續改進

if(list!=null && !list.isempty())

for(int i=0,len=list.size(); i)

//執行;

這樣效率真的會高一些嗎,實驗是最好的答案

listlist = new arraylist();

for(int i=0; i<30000000;i++)

list.add(i);

//普通迴圈

long t1 =system.currenttimemillis();

for(int j=0; j<100; j++)

for(int i=0; i)

system.out.println(system.currenttimemillis()-t1);

//改進len

t1 =system.currenttimemillis();

for(int j=0; j<100; j++)

for(int i=0, len=list.size(); i)

system.out.println(system.currenttimemillis()-t1);

//foreach方式遍歷

t1 =system.currenttimemillis();

for(int j=0; j<100; j++)

for(integer it4: list)

system.out.println(system.currenttimemillis()-t1);

結果普通for結果 22335使用len結果    14369使用foreach結果 29163

經過多次測試發現,普通for結果比len會多出三分之一左右,foreach效果比普通for會略差,而且經過多次測試發現乙個有趣的現象,迴圈位於不同的位置,結果也會有所差距,貌似jvm對迴圈過的集合會進行優化,下一次再次迴圈這個集合,速度會有所加快,這個大家也可以去做一下實驗,集合過大的時候可能報堆溢位,可以通過修改。-xms128m -xmx512m

ps:以上遍歷方法不考慮多執行緒不會有什麼問題,如果在多執行緒下遍歷將len提出來,就容易出錯了,因為len就獲取一次。

2、接下來考慮乙個問題,多執行緒下需要同步遍歷某個公共集合,如何實現

我們可能會想到用同步塊synchronized

synchronized

(list)

這樣的**真的好嗎?我們可以想一想,多執行緒的情況下,你將公共的list一鎖,其他的執行緒想插入list刪除list只能幹等著,更嚴重的是如果你在遍歷的時候還執行一些長時間的操作,例如關閉連線或者啟動監聽等等。

於是我們就想如何能夠讓等待的時間盡量的短,我們完全可以先將集合轉殖下來(至於深淺轉殖根據具體情況而論),再去執行,當然如果迴圈執行時間很短,完全沒這個必要。

lifecyclelistener interested = null;//

用轉殖減少時間,因為如果乙個乙個去觸發事件響應,得使用大量時間,而又因為執行緒鎖的存在,使得其他執行緒必須繼續等待

synchronized

(listeners)

//逐個觸發事件響應

for(int i=0; i)

為什麼上面沒有使用len中間變數,因為陣列的length並不會占用執行時間。

由雜湊表所聯想到的相關問題

c 的stl中使用了雜湊的容器類有 map multimap unordered map unordered multimap set multi set unordered set unordered multiset。map和multimap 將 key value 一組當做元素,它們可以根據 ...

由日企衰敗聯想到的運維管理問題

原文請見 前些日子看到一篇報道,說是美國cnet 刊文說,索尼的衰敗和該公司的日式文化有關,當然,也折射出日本人對自己做事方式的痴迷,即使有些方式是錯誤的。其他暫且不論,單看文章所列這些日企所表現出來的各項弊病,我想有些道理倒是放之四海而皆準的。從未重視軟體 日本公司從未真正認識到軟體的重要性,它們...

關於集合的一些問題

arraylist查詢速度快 linklist新增,刪除速度快 乙個有引數,乙個沒有引數 conllection的remove 採用鍊錶結構找出被刪除的項,要乙個乙個遍歷去找,而iterator的remove 方法結合next 方法使用,在使用iterator遍歷時,使用conllection的re...