java里怎么修改list記錄中的某個值?
1. 背景在java 中, 我們可以使用list.remove()移除list中的特定值,但是如果需要移除所有出現(xiàn)的特定值, 就值得研究一番了。 此文將會使用多種方法來嘗試解決此問題, 并說明其優(yōu)缺點。 2. 方法一: 使用簡單循環(huán)比如我們想移除某個value,很多人會這樣寫:
然而,以上代碼存在嚴重問題,例如: 對于一個List<Integer> 類型的List,當我們調(diào)用其list.remoce(int) 方法時, 實際移除的是index為 1 的值(在這個例子中是2),而不是我們想要的 value 為 1 的值。此循環(huán)將刪光除了0位的所有值, 并在最后一次循環(huán)中拋出越界異常。 我們嘗試這樣修改 如此就可以避免此問題 但是,以上代碼還有很大的優(yōu)化空間,我們接著看。 3. 方法二在上述代碼中,list.contains() 和 list.remove() 方法都查找了一次首次出現(xiàn)的值的index,這顯然是做了不必要的重復工作,我們嘗試這樣優(yōu)化代碼: 這樣就只需要查找一次index 但這段代碼仍舊擁有很大的優(yōu)化空間,因為我們沒有保留每次查找的進度,導致事實上每次查找都是從頭開始,我們嘗試繼續(xù)優(yōu)化。 4. 方法三使用for循環(huán)一次遍歷,保留了查找進度 需要注意的是,當移除value,會導致后續(xù)index全部 -1,所以我們一定要記得把index -1,否則將導致數(shù)組越界異常! 5. 方法四 使用迭代器迭代器也可以保留狀態(tài) 6. 方法五 相比于不斷修改原來的List,我們其實可以一次遍歷的同時把值寫入一個新的List,且新的List一定小于等于舊的List。對于ArrayList可以一次分配足夠的空間,避免resize的操作。 或 雖然使用了額外的存儲空間,但時間復雜度大大降低,還是值得的。 7. 方法六 使用Java 8引入的流操作其實和方法五等效,但簡單了許多 8. 方法七 使用list.removeIf() 配合 lambda表達式底層是迭代器實現(xiàn) 9. 總結(jié)其實在實際生產(chǎn)中, 使用最后兩種方法是最方便的。 對于需要大量修改的List可以使用方法六,避免多次resize 和 shifting 的性能損失,但需要額外內(nèi)存。 對于只有少量修改的List可以使用方法七。