Home Java javaTutorial Detailed explanation of the sample code of iterator in Java collection framework

Detailed explanation of the sample code of iterator in Java collection framework

Mar 21, 2017 am 10:30 AM

This article mainly provides you with a brief introduction to the relevant information about the iterator in the Java collection framework. It has certain reference value. Interested friends can refer to

Array data in Java can Obtained through index, what about objects? Also through index? Today we will analyze the method iteration-Iterator for obtaining collection objects in Java collections.

This article mainly analyzes the iterator part in the Java collection framework, Iterator. The source code analysis is based on JDK1.8, analysis tool, AndroidStudio. Please correct me if there are any deficiencies in the article analysis!

1. Introduction

We often use the iteration interface provided by JDK to iterate Java collections.

 Iterator iterator = list.iterator();
      while(iterator.hasNext()){
        String string = iterator.next();
        //do something
      }
Copy after login

The above is the basic template used by iterators. In fact, we can simply understand iteration as traversal, which is a standardized method class for traversing all objects in various containers. It always controls the Iterator and sends it the "forward", "backward", and "get current element" commands to indirectly traverse the entire collection. In Java, Iterator is an interface, which only provides basic rules for iteration:

  public interface Iterator<E> {
  //判断容器内是否还有可供访问的元素
  boolean hasNext();
  //返回迭代器刚越过的元素的引用,返回值是 E
  E next();
  //删除迭代器刚越过的元素
  default void remove() {
    throw new UnsupportedOperationException("remove");
  }
}
Copy after login

The above is the basic declaration of the iterator. We analyze it through specific collections.

2. Collection classification

2.1 Iterator of ArrayList

We can know by analyzing the source code of ArrayList that an internal class is first defined inside ArrayList Itr, the inner class implements the Iterator interface, as follows:

private class Itr implements Iterator<E> {
  //....
}
Copy after login

The inner class implements the Iterator interface, and the Iterator of ArrayList returns its inner class Itr, so we mainly look at How is Itr implemented.

  public Iterator<E> iterator() {
    return new Itr();
  }
Copy after login

Next we analyze the implementation of its internal class Itr.

  private class Itr implements Iterator<E> {

    protected int limit = ArrayList.this.size;

    int cursor;    // index of next element to return
    int lastRet = -1; // index of last element returned; -1 if no such
    int expectedModCount = modCount;

    public boolean hasNext() {
      return cursor < limit;
    }

    @SuppressWarnings("unchecked")
    public E next() {
      if (modCount != expectedModCount)
        throw new ConcurrentModificationException();
      int i = cursor;
      if (i >= limit)
        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();
      if (modCount != expectedModCount)
        throw new ConcurrentModificationException();

      try {
        ArrayList.this.remove(lastRet);
        cursor = lastRet;
        lastRet = -1;
        expectedModCount = modCount;
        limit--;
      } catch (IndexOutOfBoundsException ex) {
        throw new ConcurrentModificationException();
      }
    }

    @Override
    @SuppressWarnings("unchecked")
    public void forEachRemaining(Consumer<? super E> consumer) {
      Objects.requireNonNull(consumer);
      final int size = ArrayList.this.size;
      int i = cursor;
      if (i >= size) {
        return;
      }
      final Object[] elementData = ArrayList.this.elementData;
      if (i >= elementData.length) {
        throw new ConcurrentModificationException();
      }
      while (i != size && modCount == expectedModCount) {
        consumer.accept((E) elementData[i++]);
      }
      // update once at end of iteration to reduce heap write traffic
      cursor = i;
      lastRet = i - 1;

      if (modCount != expectedModCount)
        throw new ConcurrentModificationException();
    }
  }
Copy after login

First let’s analyze the defined variable:

    protected int limit = ArrayList.this.size;

    int cursor;    // index of next element to return
    int lastRet = -1; // index of last element returned; -1 if no such
    int expectedModCount = modCount;
Copy after login

Among them, limit is the size of the current ArrayList, cursor represents the index of the next element, and lastRet It is the index of the previous element. If not, it returns -1. expectedModCount is of little use. We will then analyze and see how to determine whether there are subsequent elements during iteration.

  public boolean hasNext() {
      return cursor < limit;
  }
Copy after login

It’s very simple, it is to determine whether the index of the next element has reached the capacity of the array. If it does, it will be gone. It’s the end!

Next, let’s analyze the method of obtaining the element of the current index next

    public E next() {
      if (modCount != expectedModCount)
        throw new ConcurrentModificationException();
      int i = cursor;
      if (i >= limit)
        throw new NoSuchElementException();
      Object[] elementData = ArrayList.this.elementData;
      if (i >= elementData.length)
        throw new ConcurrentModificationException();
      cursor = i + 1;
      return (E) elementData[lastRet = i];
    }
Copy after login

Why do we need to judge modCount in the next method? That is, it is used to determine whether the collection has been modified during the traversal process. modCount is used to record the number of modifications of the ArrayList collection. It is initialized to 0. Whenever the collection is modified (modifications on the structure, internal updates are not counted), such as add, remove and other methods, modCount + 1, so if modCount remains unchanged, It means that the collection content has not been modified. This mechanism is mainly used to implement the fast failure mechanism of the ArrayList collection. Among Java collections, a large part of the collections have fast failure mechanisms. Therefore, to ensure that no errors occur during the traversal process, we should ensure that no structural modifications are made to the collection during the traversal process (except for the remove method, of course). If an abnormal error occurs, we should carefully check whether the program has errors instead of No processing is done after catch. The above code is relatively simple, it just returns the array value at the index.

For the iteration method of ArrayList, it mainly judges the value of the index and compares it with the size of the array to see if there is no data to traverse, and then obtains the values ​​​​in the array in turn. It mainly captures each collection. The underlying implementation can be iterated.

Next we will analyze the Iterator method of HashMap. Other methods are similar, as long as you grasp the underlying implementation.

2.2 HashMap’s Iterator

In HashMap, there is also a class that implements the Iterator interface. It is just an abstract class, HashIterator. Let’s take a look at its implementation. .

 private abstract class HashIterator<E> implements Iterator<E> {
    HashMapEntry<K,V> next;    // next entry to return
    int expectedModCount;  // For fast-fail
    int index;       // current slot
    HashMapEntry<K,V> current;   // current entry

    HashIterator() {
      expectedModCount = modCount;
      if (size > 0) { // advance to first entry
        HashMapEntry[] t = table;
        while (index < t.length && (next = t[index++]) == null)
          ;
      }
    }

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

    final Entry<K,V> nextEntry() {
      if (modCount != expectedModCount)
        throw new ConcurrentModificationException();
      HashMapEntry<K,V> e = next;
      if (e == null)
        throw new NoSuchElementException();

      if ((next = e.next) == null) {
        HashMapEntry[] t = table;
        while (index < t.length && (next = t[index++]) == null)
          ;
      }
      current = e;
      return e;
    }

    public void remove() {
      if (current == null)
        throw new IllegalStateException();
      if (modCount != expectedModCount)
        throw new ConcurrentModificationException();
      Object k = current.key;
      current = null;
      HashMap.this.removeEntryForKey(k);
      expectedModCount = modCount;
    }
  }
Copy after login

Similarly, it also defines a variable

    HashMapEntry<K,V> next;    // next entry to return
    int expectedModCount;  // For fast-fail
    int index;       // current slot
    HashMapEntry<K,V> current;   // current entry
Copy after login

next represents the node of the next entry. expectedModCount is also used to determine the modified status and is used for fast collection Failure mechanism. Index represents the current index, and the node entry represented by current's current index. Let's take a look at how to determine whether there is a value for the next element.

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

It is very simple to determine whether next is null. If it is null, it means there is no data.

Then analyze the method of obtaining elements

    final Entry<K,V> nextEntry() {
      if (modCount != expectedModCount)
        throw new ConcurrentModificationException();
      HashMapEntry<K,V> e = next;
      if (e == null)
        throw new NoSuchElementException();
      // 一个Entry就是一个单向链表
      // 若该Entry的下一个节点不为空,就将next指向下一个节点;
      // 否则,将next指向下一个链表(也是下一个Entry)的不为null的节点。
      if ((next = e.next) == null) {
        HashMapEntry[] t = table;
        while (index < t.length && (next = t[index++]) == null)
          ;
      }
      current = e;
      return e;
    }
Copy after login

The above is the detailed content of Detailed explanation of the sample code of iterator in Java collection framework. For more information, please follow other related articles on the PHP Chinese website!

Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

Video Face Swap

Video Face Swap

Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Tools

Notepad++7.3.1

Notepad++7.3.1

Easy-to-use and free code editor

SublimeText3 Chinese version

SublimeText3 Chinese version

Chinese version, very easy to use

Zend Studio 13.0.1

Zend Studio 13.0.1

Powerful PHP integrated development environment

Dreamweaver CS6

Dreamweaver CS6

Visual web development tools

SublimeText3 Mac version

SublimeText3 Mac version

God-level code editing software (SublimeText3)

Perfect Number in Java Perfect Number in Java Aug 30, 2024 pm 04:28 PM

Guide to Perfect Number in Java. Here we discuss the Definition, How to check Perfect number in Java?, examples with code implementation.

Weka in Java Weka in Java Aug 30, 2024 pm 04:28 PM

Guide to Weka in Java. Here we discuss the Introduction, how to use weka java, the type of platform, and advantages with examples.

Smith Number in Java Smith Number in Java Aug 30, 2024 pm 04:28 PM

Guide to Smith Number in Java. Here we discuss the Definition, How to check smith number in Java? example with code implementation.

Java Spring Interview Questions Java Spring Interview Questions Aug 30, 2024 pm 04:29 PM

In this article, we have kept the most asked Java Spring Interview Questions with their detailed answers. So that you can crack the interview.

Break or return from Java 8 stream forEach? Break or return from Java 8 stream forEach? Feb 07, 2025 pm 12:09 PM

Java 8 introduces the Stream API, providing a powerful and expressive way to process data collections. However, a common question when using Stream is: How to break or return from a forEach operation? Traditional loops allow for early interruption or return, but Stream's forEach method does not directly support this method. This article will explain the reasons and explore alternative methods for implementing premature termination in Stream processing systems. Further reading: Java Stream API improvements Understand Stream forEach The forEach method is a terminal operation that performs one operation on each element in the Stream. Its design intention is

TimeStamp to Date in Java TimeStamp to Date in Java Aug 30, 2024 pm 04:28 PM

Guide to TimeStamp to Date in Java. Here we also discuss the introduction and how to convert timestamp to date in java along with examples.

Java Program to Find the Volume of Capsule Java Program to Find the Volume of Capsule Feb 07, 2025 am 11:37 AM

Capsules are three-dimensional geometric figures, composed of a cylinder and a hemisphere at both ends. The volume of the capsule can be calculated by adding the volume of the cylinder and the volume of the hemisphere at both ends. This tutorial will discuss how to calculate the volume of a given capsule in Java using different methods. Capsule volume formula The formula for capsule volume is as follows: Capsule volume = Cylindrical volume Volume Two hemisphere volume in, r: The radius of the hemisphere. h: The height of the cylinder (excluding the hemisphere). Example 1 enter Radius = 5 units Height = 10 units Output Volume = 1570.8 cubic units explain Calculate volume using formula: Volume = π × r2 × h (4

Create the Future: Java Programming for Absolute Beginners Create the Future: Java Programming for Absolute Beginners Oct 13, 2024 pm 01:32 PM

Java is a popular programming language that can be learned by both beginners and experienced developers. This tutorial starts with basic concepts and progresses through advanced topics. After installing the Java Development Kit, you can practice programming by creating a simple "Hello, World!" program. After you understand the code, use the command prompt to compile and run the program, and "Hello, World!" will be output on the console. Learning Java starts your programming journey, and as your mastery deepens, you can create more complex applications.

See all articles