2011-05-23 48 views
3

我有一個循環通過ArrayList的for循環。Java三元運算符和設置循環索引值

如果條件是滿足的for循環:

  • 我刪除從ArrayList
  • 當前元素減少ArrayList局部變量的大小
  • 減少for循環的指數,像這樣,檢查以確保它們永遠不會低於零。

,我們剛纔刪除的ArrayList的最後一個元素的情況:

i = (i > 0) ? i-- : i; 

我的問題是,上面並沒有減少1我當我> 0。我用三元運營商無數次,但從未見過這種行爲。我測試過我確實是> 0,並且i--部分被調用。它根本不會降低我的價值。取消0值檢查並簡單地運行i--;的確會降低我的預期。

編輯2:好吧,有人編輯了我最後的編輯,我提到我在這種情況下特別不使用ListIterator,因爲循環本身的性能敏感的本質,在Android代碼的關鍵部分。

回答

6

i--遞減i,但返回值。

i = i--將遞減i,然後將其分配給其原始值。

您應該使用i - 1

+0

當然要歸功於 – 2011-05-23 16:24:11

4

最小的解決辦法:

你可能是這樣的後:

for (int i = 0; i < l.size(); i++) {   <--------------------------------. 
    if (cond) {                | 
     l.remove(i);               | 
     i--;    // even if i == -1, it will be set back to 0 here --' 
    } 
} 

向後迭代來代替:

另一種常見的解決方案是向後遍歷,像這個:

for (int i = l.size() - 1; i >= 0; i--) { 
    if (cond) { 
     l.remove(i); 
    } 
} 

使用ListIterator(除非高度性能的關鍵):

但是,你即使有ListIterator更好關:

Iterator<String> iter = l.iterator(); 
while (iter.hasNext()) { 
    if (shouldRemove(iter.next()) 
     iter.remove(); 
} 
2

具有分配如i = i-- (這發生在i > 0)根本沒有意義:你到底在想什麼回覆?改用以下內容:

i = (i > 0) ? i - 1 : i; 

,或者甚至更好:

if (i > 0) 
    i--; 
2

做正確的事:用一個迭代循環在你的數組列表和安全地刪除,而迭代的項目。

3

你嘗試?:

i = (i > 0) ? --i : i; 

隨着你應該解決所有的問題預先遞減。

+0

在這裏組合使用遞減運算符和'I = ...'是多餘的(和誤導)。 – 2011-05-23 22:16:52

2

你所描述的算法對於你所要做的是一個糟糕的策略:從ArrayList中移除一個元素是一個O(n)操作,所以把它應用到整個ArrayList中是O(n^2)一般情況。

一個更好的策略:

  • 通過原來的ArrayList創建一個新的空的ArrayList
  • 循環一次,並且只添加您希望保留到新的ArrayList元素

這爲O(n),並且實際上是簡單的代碼(你不必擔心與循環邊界等等擺弄)

+0

+1這不回答我有(我頒發這個問題的答案給別人)的特異三元的問題,但確實更有意義在我的去除O(n)的某些項目的更大的目標方面,由於我沒有考慮到ArrayList.remove()也是O(n)。謝謝! – 2011-05-23 16:23:07

1

考慮不使用三元操作符機智h noop。

如果(I> 0){ --i }

準確描述你想要的功能(根據你的例子)。

1

正如其他人所說,i--遞減i並返回原始值,這意味着您的代碼將執行遞減,但立即將其設置回其原始值。

你可以圍繞其切換爲--i,在這種情況下遞減的值將被退回,但無論哪種方式,你正在做與--非必要的工作,因爲它有設定i,返回新值,然後再將i設置爲新值。

你會更好,只是在做i-1,這將不設置的i值的兩倍:

i = (i > 0) ? i-1 : i; 

一切都表示,因爲三元的錯誤選項並不做任何事情,你「大概d是隻使用一個簡單的if()的更好:

if(i > 0) { i--; } 

它更容易閱讀,輪--去,並沒有做任何多餘的處理,不論結果如何並不重要途徑。