java 中iterator 和 collection接口源码
iterator接口和具體的容器中實現的iterator 對象(以ArrayList為例)
iterator:
private class Itr implements Iterator<E> {/**元素的下標* Index of element to be returned by subsequent call to next.*/int cursor = 0;/**上一個元素的下標。如果元素已被刪除就設置為-1* Index of element returned by most recent call to next or* previous. Reset to -1 if this element is deleted by a call* to remove.*/int lastRet = -1;/**允許修改的次數,違規操作會拋異常* The modCount value that the iterator believes that the backing* List should have. If this expectation is violated, the iterator* has detected concurrent modification.*/int expectedModCount = modCount;/*檢查是否還有下一個元素*/public boolean hasNext() {return cursor != size();}/*光標下移,并且返回當前的元素*/public E next() {checkForComodification();try {int i = cursor;E next = get(i);lastRet = i;cursor = i + 1;return next;} catch (IndexOutOfBoundsException e) {checkForComodification();throw new NoSuchElementException();}}/*移除元素*/public void remove() {if (lastRet < 0)throw new IllegalStateException();checkForComodification();try {AbstractList.this.remove(lastRet);if (lastRet < cursor)cursor--;lastRet = -1;expectedModCount = modCount;} catch (IndexOutOfBoundsException e) {throw new ConcurrentModificationException();}}final void checkForComodification() {if (modCount != expectedModCount)throw new ConcurrentModificationException();}}
ArrayList中的iterator()方法:
public Iterator<E> iterator() {return new Itr();}collection 源碼:
/** * Collection是所有collection類的根接口; * Collection繼承了Iterable,即所有的Collection中的類都能使用foreach方法。 * @author WGS * @param <E> */ public interface Collection<E> extends Iterable<E> {//返回集合中元素的大小。(如果此大小值超過Integer.MAX_VALUE,就直接返回Integer.MAX_VALUE) int size();//判斷集合是否為空 Boolean isEmpty();//判斷集合是否包含元素o(注意元素e是否為null及類型是否兼容問題) Boolean contains(Object o);//返回集合中元素的迭代器(順序不能保證,除非集合指定了順序) Iterator<E> iterator();//以數組的形式返回集合中的所有元素,數組是安全 Object[] toArray();//以數組形式返回指定數組類型的集合元素 <T> T[] toArray(T[] a);//此方法可用來判斷集合中是否含有元素e;是-false,否-true(在set,map中會經常調用這個方法,在編程題時很有用) Boolean add(E e);//從集合中移除指定的元素 Boolean remove(Object o);//用來判斷是否含有指定集合中的所以元素 Boolean containsAll(Collection<?> c);//將指定集合中的所有元素添加至調用者的集合中 Boolean addAll(Collection<? extends E> c);//移除與指定集合相同的元素(即移除兩集合交集部分) Boolean removeAll(Collection<?> c);//保留與指定集合中相同的元素(即移除與指定集合不同的元素) Boolean retainAll(Collection<?> c);//清空集合 void clear();//判斷與指定元素是否相等 Boolean equals(Object o);//返回集合的哈希碼值 int hashCode(); }因為在你迭代之前,迭代器已經被通過list.itertor()創建出來了,如果在迭代的過程中,又對list進行了改變其容器大小的操作,那么Java就會給出異常。因為此時Iterator對象已經無法主動同步list做出的改變,Java會認為你做出這樣的操作是線程不安全的,就會給出善意的提醒(拋出ConcurrentModificationException異常)
通過查看源碼發現原來檢查并拋出異常的是checkForComodification()方法。在ArrayList中modCount是當前集合的版本號,每次修改(增、刪)集合都會加1;expectedModCount是當前迭代器的版本號,在迭代器實例化時初始化為modCount。我們看到在checkForComodification()方法中就是在驗證modCount的值和expectedModCount的值是否相等,所以當你在調用了ArrayList.add()或者ArrayList.remove()時,只更新了modCount的狀態,而迭代器中的expectedModCount未同步,因此才會導致再次調用Iterator.next()方法時拋出異常。但是為什么使用Iterator.remove()就沒有問題呢?通過源碼的第32行發現,在Iterator的remove()中同步了expectedModCount的值,所以當你下次再調用next()的時候,檢查不會拋出異常。
使用該機制的主要目的是為了實現ArrayList中的快速失敗機制(fail-fast),在Java集合中較大一部分集合是存在快速失敗機制的。
快速失敗機制產生的條件:當多個線程對Collection進行操作時,若其中某一個線程通過Iterator遍歷集合時,該集合的內容被其他線程所改變,則會拋出ConcurrentModificationException異常。
所以要保證在使用Iterator遍歷集合的時候不出錯誤,就應該保證在遍歷集合的過程中不會對集合產生結構上的修改。
總結
以上是生活随笔為你收集整理的java 中iterator 和 collection接口源码的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 腾达 NH326 无线路由器设置网速控制
- 下一篇: 鲁迅的名人名言 鲁迅有哪些名人名言