java 中iterator 和 collection接口源码
iterator接口和具體的容器中實(shí)現(xiàn)的iterator 對象(以ArrayList為例)
iterator:
private class Itr implements Iterator<E> {/**元素的下標(biāo)* Index of element to be returned by subsequent call to next.*/int cursor = 0;/**上一個(gè)元素的下標(biāo)。如果元素已被刪除就設(shè)置為-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;/**允許修改的次數(shù),違規(guī)操作會(huì)拋異常* 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;/*檢查是否還有下一個(gè)元素*/public boolean hasNext() {return cursor != size();}/*光標(biāo)下移,并且返回當(dāng)前的元素*/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();//以數(shù)組的形式返回集合中的所有元素,數(shù)組是安全 Object[] toArray();//以數(shù)組形式返回指定數(shù)組類型的集合元素 <T> T[] toArray(T[] a);//此方法可用來判斷集合中是否含有元素e;是-false,否-true(在set,map中會(huì)經(jīng)常調(diào)用這個(gè)方法,在編程題時(shí)很有用) Boolean add(E e);//從集合中移除指定的元素 Boolean remove(Object o);//用來判斷是否含有指定集合中的所以元素 Boolean containsAll(Collection<?> c);//將指定集合中的所有元素添加至調(diào)用者的集合中 Boolean addAll(Collection<? extends E> c);//移除與指定集合相同的元素(即移除兩集合交集部分) Boolean removeAll(Collection<?> c);//保留與指定集合中相同的元素(即移除與指定集合不同的元素) Boolean retainAll(Collection<?> c);//清空集合 void clear();//判斷與指定元素是否相等 Boolean equals(Object o);//返回集合的哈希碼值 int hashCode(); }因?yàn)樵谀愕?#xff0c;迭代器已經(jīng)被通過list.itertor()創(chuàng)建出來了,如果在迭代的過程中,又對list進(jìn)行了改變其容器大小的操作,那么Java就會(huì)給出異常。因?yàn)榇藭r(shí)Iterator對象已經(jīng)無法主動(dòng)同步list做出的改變,Java會(huì)認(rèn)為你做出這樣的操作是線程不安全的,就會(huì)給出善意的提醒(拋出ConcurrentModificationException異常)
通過查看源碼發(fā)現(xiàn)原來檢查并拋出異常的是checkForComodification()方法。在ArrayList中modCount是當(dāng)前集合的版本號,每次修改(增、刪)集合都會(huì)加1;expectedModCount是當(dāng)前迭代器的版本號,在迭代器實(shí)例化時(shí)初始化為modCount。我們看到在checkForComodification()方法中就是在驗(yàn)證modCount的值和expectedModCount的值是否相等,所以當(dāng)你在調(diào)用了ArrayList.add()或者ArrayList.remove()時(shí),只更新了modCount的狀態(tài),而迭代器中的expectedModCount未同步,因此才會(huì)導(dǎo)致再次調(diào)用Iterator.next()方法時(shí)拋出異常。但是為什么使用Iterator.remove()就沒有問題呢?通過源碼的第32行發(fā)現(xiàn),在Iterator的remove()中同步了expectedModCount的值,所以當(dāng)你下次再調(diào)用next()的時(shí)候,檢查不會(huì)拋出異常。
使用該機(jī)制的主要目的是為了實(shí)現(xiàn)ArrayList中的快速失敗機(jī)制(fail-fast),在Java集合中較大一部分集合是存在快速失敗機(jī)制的。
快速失敗機(jī)制產(chǎn)生的條件:當(dāng)多個(gè)線程對Collection進(jìn)行操作時(shí),若其中某一個(gè)線程通過Iterator遍歷集合時(shí),該集合的內(nèi)容被其他線程所改變,則會(huì)拋出ConcurrentModificationException異常。
所以要保證在使用Iterator遍歷集合的時(shí)候不出錯(cuò)誤,就應(yīng)該保證在遍歷集合的過程中不會(huì)對集合產(chǎn)生結(jié)構(gòu)上的修改。
總結(jié)
以上是生活随笔為你收集整理的java 中iterator 和 collection接口源码的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 腾达 NH326 无线路由器设置网速控制
- 下一篇: 鲁迅的名人名言 鲁迅有哪些名人名言