前言
平時最常用的莫過於ArrayList
和HashMap
了,面試的時候也是問答的常客。先不去管容量、負載因子什麼的,就是簡單的使用也會遇到坑。
Remove 元素
經常遇到的一個場景是:遍歷list, 然後找到合適條件的給刪除掉,比如刪除所有的偶數。
@Test
public void testRemove2(){
List<Integer> integers = new ArrayList<>(5);
integers.add(1);
integers.add(2);
integers.add(2);
integers.add(4);
integers.add(5);
for (int i = 0; i < integers.size(); i++) {
if (integers.get(i)%2==0){
integers.remove(i);
}
}
System.out.println(integers);
}複製程式碼
看起來好像沒問題,加入面試的時候當面問:輸出結果是什麼?再問真不會報錯嗎?再問結果是什麼?
- 報錯
- 結果是空list
- 結果是[1, 2, 5]
List.remove()有兩個,一個public E remove(int index)
,一個是public boolean remove(Object o)
,那下面的結果是什麼:
@Test
public void testRemove(){
ArrayList<Integer> integers = Lists.newArrayList(1, 2, 3, 4);
System.out.println(integers);
integers.remove(1);
System.out.println(integers);
}複製程式碼
- [1, 3, 4]
經常會使用一個Arrays.asList的API, 那麼下面的結果是什麼:
@Test
public void testRemove3(){
List<String> list = Arrays.asList("a","b");
list.add("c");
System.out.println(list);
}複製程式碼
- 報錯: java.lang.UnsupportedOperationException
使用foreach是否可以實現剛開始的問題
@Test
public void testRemove4(){
List<String> strings = new ArrayList<>();
strings.add("a");
strings.add("b");
strings.add("c");
strings.add("d");
for (String string : strings) {
strings.remove(string);
}
}複製程式碼
- 否,報錯java.util.ConcurrentModificationException
為了效能問題,我們推薦把list.size的計算提取出來
@Test
public void testRemove5(){
List<String> strings = new ArrayList<>();
strings.add("a");
strings.add("b");
strings.add("c");
strings.add("d");
int size = strings.size();
for (int i = 0; i < size; i++) {
strings.remove(i);
}
}複製程式碼
- 報錯: java.lang.IndexOutOfBoundsException: Index: 2, Size: 2
- 這是很好的習慣, 不像開頭那樣每次迴圈都計算一次size,而且按這種情況還可以再執行的時候報錯。文初的做法不報錯,但結果並不是我們想要的。
使用Iterator是不是就可以remove了
@Test
public void testRemove6(){
List<String> strings = new ArrayList<>();
strings.add("a");
strings.add("b");
strings.add("c");
strings.add("d");
Iterator<String> iterator = strings.iterator();
while (iterator.hasNext()){
String next = iterator.next();
strings.remove(next);
}
System.out.println(strings);
}複製程式碼
- 報錯: java.util.ConcurrentModificationException
正確的remove做法是什麼
@Test
public void testRemove7(){
List<String> strings = new ArrayList<>();
strings.add("a");
strings.add("b");
strings.add("c");
strings.add("d");
Iterator<String> iterator = strings.iterator();
while (iterator.hasNext()){
String next = iterator.next();
iterator.remove();
}
System.out.println(strings);
}複製程式碼