大家都看新闻了,最近石家庄疫情有新增。希望国际站能早日战胜!
踩坑迭代器
是不是有人在遍历删除List集合里的数据的时候遇到了某些问题?
简单用法
Collection collection =newArrayList();collection.add("Dao");collection.add("Sen");// 迭代器Iterator iterator = collection.iterator();while(iterator.hasNext()) {String item = iterator.next();System.out.println(item);// 打印完如果需要从集合删除iterator.remove()}复制代码
介绍常用的三个方法
hasNext():返回boolean,表示判断是否存在下一个元素
next():返回集合当前元素
remove():删除当前元素
来看一下ArrayList的iterator实现方式
privateclassItrimplementsIterator{// 将要next返回元素的索引intcursor =0;// 当前返回的元素的索引,初始值-1intlastRet = -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.
*/intexpectedModCount = modCount;publicbooleanhasNext(){// 由于cursor是将要返回元素的索引,也就是下一个元素的索引,和size比较是否相等,也就是判断是否已经next到最后一个元素returncursor != size(); }publicEnext(){ checkForComodification();try{// 根据下一个元素索引取出对应元素E next = get( cursor);// 更新lastRet为当前元素的索引,cursor加1lastRet = cursor ++;// 返回元素returnnext; }catch(IndexOutOfBoundsException e) { checkForComodification();thrownewNoSuchElementException(); } }publicvoidremove(){// remove前必须先next一下,先取得当前元素if(lastRet == -1)thrownewIllegalStateException(); checkForComodification();try{ AbstractList.this.remove(lastRet );// 确保lastRet比cursor小、理论上永远lastRet比cursor小1if(lastRet < cursor)// 由于删除了一个元素cursor回退1cursor--;// 重置为-1lastRet = -1; expectedModCount = modCount ; }catch(IndexOutOfBoundsException e) {thrownewConcurrentModificationException(); } }finalvoidcheckForComodification(){if(modCount != expectedModCount)thrownewConcurrentModificationException(); }}复制代码
再来看看LinkedList的Iterator实现
LinkedList的Iterator实现定义在AbstracSequentialtList中,实现在AbstractList中
AbstracSequentialtList的定义:
publicIteratoriterator(){returnlistIterator();}复制代码
AbstractList的实现:
publicListIteratorlistIterator(){returnlistIterator(0);}publicListIteratorlistIterator(finalintindex){if(index<0|| index>size())thrownewIndexOutOfBoundsException("Index: "+index);returnnewListItr(index);}复制代码
ListItr实现:
private class ListItr implements ListIterator<E> { // 最后一次返回的节点,默认位header节点 private Entry<E> lastReturned = header; // 将要返回的节点 private Entry<E> next ; // 将要返回的节点index索引 private int nextIndex; private int expectedModCount = modCount; ListItr( int index) { // 索引越界检查 if (index < 0 || index > size) throw new IndexOutOfBoundsException( "Index: "+index+ ", Size: "+size ); // 简单二分,判断遍历的方向 if (index < (size >> 1)) { // 取得index位置对应的节点 next = header .next; for (nextIndex =0; nextIndex<index; nextIndex++) next = next .next; } else { next = header ; for (nextIndex =size; nextIndex>index; nextIndex --) next = next .previous; } } public boolean hasNext() { // 根据下一个节点index是否等于size,判断是否有下一个节点 return nextIndex != size; } public E next() { checkForComodification(); // 遍历完成 if (nextIndex == size) throw new NoSuchElementException(); // 赋值最近一次返回的节点 lastReturned = next ; // 赋值下一次要返回的节点(next后移) next = next .next; // 将要返回的节点index索引+1 nextIndex++; return lastReturned .element; } public boolean hasPrevious() { return nextIndex != 0; } // 返回上一个节点(双向循环链表嘛、可以两个方向遍历) public E previous() { if (nextIndex == 0) throw new NoSuchElementException(); lastReturned = next = next. previous; nextIndex--; checkForComodification(); return lastReturned .element; } public int nextIndex() { return nextIndex ; } public int previousIndex() { return nextIndex -1; } public void remove() { checkForComodification(); // 取出当前返回节点的下一个节点 Entry<E> lastNext = lastReturned.next ; try { LinkedList. this.remove(lastReturned ); } catch (NoSuchElementException e) { throw new IllegalStateException(); } // 确认下次要返回的节点不是当前节点,如果是则修正 if (next ==lastReturned) next = lastNext; else // 由于删除了一个节点,下次要返回的节点索引-1 nextIndex--; // 重置lastReturned为header节点 lastReturned = header ; expectedModCount++; } public void set(E e) { if (lastReturned == header) throw new IllegalStateException(); checkForComodification(); lastReturned.element = e; } public void add(E e) { checkForComodification(); lastReturned = header ; addBefore(e, next); nextIndex++; expectedModCount++; } final void checkForComodification() { if (modCount != expectedModCount) throw new ConcurrentModificationException(); } }
介绍完毕,希望国际站疫情也到此为止。
网友评论