当前位置 主页 > 网站技术 > 代码类 >

    Java中Set&List的迭代器实现步骤解析

    栏目:代码类 时间:2019-10-21 12:04

    List

    Java 的list又分为 ArrayList 和 LinkedList

    ArrayList

    private class Itr implements Iterator<E> {
        int cursor;    // index of next element to return
        int lastRet = -1; // index of last element returned; -1 if no such
        int expectedModCount = modCount;
    
        // prevent creating a synthetic constructor
        Itr() {}
    
        public boolean hasNext() {
          return cursor != size;
        }
    
        @SuppressWarnings("unchecked")
        public E next() {
          checkForComodification();
          int i = cursor;
          if (i >= size)
            throw new NoSuchElementException();
          Object[] elementData = ArrayList.this.elementData;
          if (i >= elementData.length)
            throw new ConcurrentModificationException();
          cursor = i + 1;
          return (E) elementData[lastRet = i];
        }
    
        public void remove() {
          if (lastRet < 0)
            throw new IllegalStateException();
          checkForComodification();
    
          try {
            ArrayList.this.remove(lastRet);
            cursor = lastRet;
            lastRet = -1;
            expectedModCount = modCount;
          } catch (IndexOutOfBoundsException ex) {
            throw new ConcurrentModificationException();
          }
        }
      }

    从代码中我们不难看出迭代器维护上一次return的元素下边和下一个将要return的元素下标,并且迭代器在进行修改操作时会检查在本次操作与上次操作之间是否有迭代器以外的操作,并且适时抛出ConcurrentModificationException(并发修改异常)来阻止更多错误的发生

    LinkedList

    private class ListItr implements ListIterator<E> {
        private Node<E> lastReturned;
        private Node<E> next;
        private int nextIndex;
        private int expectedModCount = modCount;
    
        ListItr(int index) {
          // assert isPositionIndex(index);
          next = (index == size) ? null : node(index);
          nextIndex = index;
        }
    
        public boolean hasNext() {
          return nextIndex < size;
        }
    
        public E next() {
          checkForComodification();
          if (!hasNext())
            throw new NoSuchElementException();
    
          lastReturned = next;
          next = next.next;
          nextIndex++;
          return lastReturned.item;
        }
    
        public boolean hasPrevious() {
          return nextIndex > 0;
        }
    
        public E previous() {
          checkForComodification();
          if (!hasPrevious())
            throw new NoSuchElementException();
    
          lastReturned = next = (next == null) ? last : next.prev;
          nextIndex--;
          return lastReturned.item;
        }
    
        public int nextIndex() {
          return nextIndex;
        }
    
        public int previousIndex() {
          return nextIndex - 1;
        }
    
        public void remove() {
          checkForComodification();
          if (lastReturned == null)
            throw new IllegalStateException();
    
          Node<E> lastNext = lastReturned.next;
          unlink(lastReturned);
          if (next == lastReturned)
            next = lastNext;
          else
            nextIndex--;
          lastReturned = null;
          expectedModCount++;
        }
    
        public void set(E e) {
          if (lastReturned == null)
            throw new IllegalStateException();
          checkForComodification();
          lastReturned.item = e;
        }
    
        public void add(E e) {
          checkForComodification();
          lastReturned = null;
          if (next == null)
            linkLast(e);
          else
            linkBefore(e, next);
          nextIndex++;
          expectedModCount++;
        }
    
        public void forEachRemaining(Consumer<? super E> action) {
          Objects.requireNonNull(action);
          while (modCount == expectedModCount && nextIndex < size) {
            action.accept(next.item);
            lastReturned = next;
            next = next.next;
            nextIndex++;
          }
          checkForComodification();
        }
    
        final void checkForComodification() {
          if (modCount != expectedModCount)
            throw new ConcurrentModificationException();
        }
      }