欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java中Set&List的迭代器實(shí)現(xiàn)步驟解析

 更新時(shí)間:2019年10月21日 11:32:03   作者:一只不太會(huì)游泳的魚  
這篇文章主要介紹了Java中Set&List的迭代器實(shí)現(xiàn)步驟解析,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下

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();
      }
    }
  }

從代碼中我們不難看出迭代器維護(hù)上一次return的元素下邊和下一個(gè)將要return的元素下標(biāo),并且迭代器在進(jìn)行修改操作時(shí)會(huì)檢查在本次操作與上次操作之間是否有迭代器以外的操作,并且適時(shí)拋出ConcurrentModificationException(并發(fā)修改異常)來阻止更多錯(cuò)誤的發(fā)生

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();
    }
  }

LinkedList的迭代器類的實(shí)現(xiàn)邏輯與ArrayList大致相近但是其訪問元素的方式由原來的下標(biāo)變?yōu)?"指針"(Java強(qiáng)引用)

Set

通過看Java源碼可以知道Set全家桶基本上都包含了Map,相當(dāng)于是一種組合的方式

HashSet

構(gòu)造方法

HashSet有多個(gè)構(gòu)造方法但都是初始化一個(gè)HashMap或其子類

/**
   * Constructs a new, empty set; the backing {@code HashMap} instance has
   * default initial capacity (16) and load factor (0.75).
   */
  public HashSet() {
    map = new HashMap<>();
  }

  /**
   * Constructs a new set containing the elements in the specified
   * collection. The {@code HashMap} is created with default load factor
   * (0.75) and an initial capacity sufficient to contain the elements in
   * the specified collection.
   *
   * @param c the collection whose elements are to be placed into this set
   * @throws NullPointerException if the specified collection is null
   */
  public HashSet(Collection<? extends E> c) {
    map = new HashMap<>(Math.max((int) (c.size()/.75f) + 1, 16));
    addAll(c);
  }

  /**
   * Constructs a new, empty set; the backing {@code HashMap} instance has
   * the specified initial capacity and the specified load factor.
   *
   * @param   initialCapacity  the initial capacity of the hash map
   * @param   loadFactor    the load factor of the hash map
   * @throws   IllegalArgumentException if the initial capacity is less
   *       than zero, or if the load factor is nonpositive
   */
  public HashSet(int initialCapacity, float loadFactor) {
    map = new HashMap<>(initialCapacity, loadFactor);
  }

  /**
   * Constructs a new, empty set; the backing {@code HashMap} instance has
   * the specified initial capacity and default load factor (0.75).
   *
   * @param   initialCapacity  the initial capacity of the hash table
   * @throws   IllegalArgumentException if the initial capacity is less
   *       than zero
   */
  public HashSet(int initialCapacity) {
    map = new HashMap<>(initialCapacity);
  }

  /**
   * Constructs a new, empty linked hash set. (This package private
   * constructor is only used by LinkedHashSet.) The backing
   * HashMap instance is a LinkedHashMap with the specified initial
   * capacity and the specified load factor.
   *
   * @param   initialCapacity  the initial capacity of the hash map
   * @param   loadFactor    the load factor of the hash map
   * @param   dummy       ignored (distinguishes this
   *       constructor from other int, float constructor.)
   * @throws   IllegalArgumentException if the initial capacity is less
   *       than zero, or if the load factor is nonpositive
   */
  HashSet(int initialCapacity, float loadFactor, boolean dummy) {
    map = new LinkedHashMap<>(initialCapacity, loadFactor);
  }

iterator方法

該接口在HashSet中的實(shí)現(xiàn)相當(dāng)?shù)暮唵?可以看到iterator返回了keySet().iterator()

public Iterator<E> iterator() {
    return map.keySet().iterator();
  }

HashMap的KeySet

從這一處代碼可以看到iterator()返回了對象 KeyIterator

final class KeySet extends AbstractSet<K> {
    public final int size()         { return size; }
    public final void clear()        { HashMap.this.clear(); }
    public final Iterator<K> iterator()   { return new KeyIterator(); }
    public final boolean contains(Object o) { return containsKey(o); }
    public final boolean remove(Object key) {
      return removeNode(hash(key), key, null, false, true) != null;
    }
    public final Spliterator<K> spliterator() {
      return new KeySpliterator<>(HashMap.this, 0, -1, 0, 0);
    }
    public final void forEach(Consumer<? super K> action) {
      Node<K,V>[] tab;
      if (action == null)
        throw new NullPointerException();
      if (size > 0 && (tab = table) != null) {
        int mc = modCount;
        for (Node<K,V> e : tab) {
          for (; e != null; e = e.next)
            action.accept(e.key);
        }
        if (modCount != mc)
          throw new ConcurrentModificationException();
      }
    }
  }

HashMap的KeyIterator

KeyIterator是HashIterator一個(gè)子類在此一并展示了,這個(gè)類從字段結(jié)構(gòu)上跟LinkedList的ListItr還是很像的

獲取next的機(jī)制 Node<K,V> 內(nèi)部本身包含一個(gè)next引用當(dāng)HashIterator或其子類對象調(diào)用方法nextNode時(shí),若該引用非空者優(yōu)先返回該引用指向的對象,否則掩蓋引用的index在HashMap內(nèi)部的 Node<K,V> 數(shù)組table中向后找, 直到找到一個(gè)不為空的引用,或者到table結(jié)束也沒有找到, 那么此時(shí)返回空引用

abstract class HashIterator {
    Node<K,V> next;    // next entry to return
    Node<K,V> current;   // current entry
    int expectedModCount; // for fast-fail
    int index;       // current slot

    HashIterator() {
      expectedModCount = modCount;
      Node<K,V>[] t = table;
      current = next = null;
      index = 0;
      if (t != null && size > 0) { // advance to first entry
        do {} while (index < t.length && (next = t[index++]) == null);
      }
    }

    public final boolean hasNext() {
      return next != null;
    }

    final Node<K,V> nextNode() {
      Node<K,V>[] t;
      Node<K,V> e = next;
      if (modCount != expectedModCount)
        throw new ConcurrentModificationException();
      if (e == null)
        throw new NoSuchElementException();
      if ((next = (current = e).next) == null && (t = table) != null) {
        do {} while (index < t.length && (next = t[index++]) == null);
      }
      return e;
    }

    public final void remove() {
      Node<K,V> p = current;
      if (p == null)
        throw new IllegalStateException();
      if (modCount != expectedModCount)
        throw new ConcurrentModificationException();
      current = null;
      removeNode(p.hash, p.key, null, false, false);
      expectedModCount = modCount;
    }
  }

  final class KeyIterator extends HashIterator
    implements Iterator<K> {
    public final K next() { return nextNode().key; }
  }

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

最新評論