目錄
4、LinkedList的pollFirst/pollLast和removeFirst/removeLast方法
一、Collection實現類的遍歷方式
Collection接口繼承了Iterable接口,因此其子接口List、Set和Queue的實現類都擁有迭代器(Iterator),因此Collection接口下實現類的遍歷方式通常有循環+get()隨機訪問、foreach循環訪問和迭代器訪問三種方式。
1、循環加隨機訪問get(index)
int size = list.size();
for (int i=0; i<size; i++) {
System.out.print(list.get(i));
}
2、foreach循環
for (E e:list){
System.out.println(e);
}
3、迭代器
Iterator iter = list.iterator();
//Iterator iter = set.iterator();
//Iterator iter = queue.iterator();
while(iter.hasNext()){
System.out.println(iter.next());
}
而List接口還實現了Iterable接口的子接口ListIterator,可以實現雙向的迭代器遍歷
ListIterator iter = list.ListIterator()
while(iter.hasNext()){
System.out.println(iter.next());
}
while(iter.hasPrevious()){
System.out.println(iter.Previous());
}
4、LinkedList的pollFirst/pollLast和removeFirst/removeLast方法
除了上述的遍歷方式,由於LinkedList是基於雙向鏈表實現的,因此他的pollFirst/pollLast和removeFirst/removeLast也可以實現類似迭代器的效果,只是這些方法是要從LinkedList中刪除元素的
pollFirst/pollLast:
Object ii;
while((ii=ll.pollFirst())!=null){
System.out.println(ii);
}
同理removeFirst/removeLast:
Object ii;
while((ii=ll.removeFirst())!=null){
System.out.println(ii);
}
//打印完所有元素後會拋出NoSuchElementException異常
但是這裏有個區別就是,pollFirst/pollLast在list沒有元素的時候返回null,而removeFirst/removeLast在list爲空的時候拋出NoSuchElementException異常。
速度:removeFirst/removeLast>foreach循環>pollFirst/pollLast>迭代器>循環加隨機訪問get(index)
但是注意,pollFirst/pollLast和removeFirst/removeLast會刪除元素,所以最好是使用foreach循環或者迭代器,反正對LinkedList一定不要用循環加隨機訪問的方式,這是因爲每一次get操作都是從鏈表頭(尾)遍歷最多size/2個元素後才能訪問到,是非常消耗資源的。
二、元素的刪除
元素的刪除是依賴於元素的遍歷的,首先要遍歷集合,發現與刪除目標相等的元素時對改元素進行刪除,但是要注意下標的變化
1、利用迭代器進行刪除(推薦,不會需要考慮下標的變化)
Object toBeRemoved=3;
while(iter.hasNext()){
Object value=iter.next();
if(value.equals(toBeRemoved)){
iter.remove(); //注意此處是iter.remove()
}
}
注意,如果把iter.remove()換成list.remove()則會拋出ConcurrentModificationException
2、利用循環加隨機訪問的方式比較刪除目標元素(需要注意下標的變化)
int size=ll.size();
Object toBeRemoved=3;
for(int j=0;j<size;j++){
Object value=ll.get(j);
if(value.equals(toBeRemoved)){
ll.remove(j);
j--;
size--; //注意這兩處下標j和size的變化
}
}
注意此處採用的是list.remove()方法,但是同時就需要注意下標j和集合大小size的變化,如果沒有j--或size--會出現IndexOutOfBoundsException異常
3、利用反向循環加隨機訪問
for (int i = list.size() - 1;i > 0; i--) {
Object value = list.get(i);
if(value.equals(toRemoveValue)) {
list.remove(i);
}
}
4、利用list的removeAll方法
List toRemoveList = new ArrayList<>();
for (int i = 0; i < list.size(); i++) {
Object value = list.get(i);
if(value.equals(toRemoveValue)) {
toRemoveList.add(value);
}
}
list.removeAll(toRemoveList);
5、list的removeIf方法和java8新特性
list.removeIf(value -> value==toRemoveValue);
6、利用java8的過濾新特性
list.stream().filter(value -> value!=toRemoveValue).forEach(System.out::println);
list.stream().forEach(value -> { if(value!=toRemoveValue) System.out.println(value);});
注意,以上兩個方法其實不是刪除,是在打印的時候過濾掉要刪除的元素不打印,list裏面的元素並沒有被刪除掉