Iterator & Iterable

Enhanced for loop:

Set<Integer> set = new TreeSet<>();
for (Integer num : set) {
    System.out.println(num);
}

This is a syntactic sugar, compiled into byte code, the compiler will be replaced iterator: syntactic sugar solution (desugar)

  • First call Set.iterator
  • Then call Iterator.hasNext
  • Last call Iterator.next

Note: Enhanced for loop array type is not the same, using for-i is implemented.

L1
    LINENUMBER 9 L1
    ALOAD 1
    INVOKEINTERFACE java/util/Set.iterator ()Ljava/util/Iterator; (itf)
    ASTORE 2
L2
    FRAME APPEND [java/util/Set java/util/Iterator]
    ALOAD 2
    INVOKEINTERFACE java/util/Iterator.hasNext ()Z (itf)
    IFEQ L3
    ALOAD 2
    INVOKEINTERFACE java/util/Iterator.next ()Ljava/lang/Object; (itf)
    CHECKCAST java/lang/Integer
    ASTORE 3
L4
    LINENUMBER 10 L4
    GETSTATIC java/lang/System.out : Ljava/io/PrintStream;
    ALOAD 3
    INVOKEVIRTUAL java/io/PrintStream.println (Ljava/lang/Object;)V

Syntactic sugar:

  • Automatic entry boxes is syntactic sugar, the compiler will be replaced Integer.valueOf (), etc.

Why do we need iterators:

For different collections, they have their own traversal patterns.

Is there a way that the set may be sequentially accessed in each element, but does not require the internal representation of the object is exposed.

Design Patterns: Iterator mode

public interface Iterator<E> {
	// 返回true如果迭代对象还存在元素
    boolean hasNext();

    // 返回迭代对象中的下一个元素。如果不存在则抛出NoSuchElementException
    E next();

    // 删除此迭代器返回的最后一个元素(可选)。此方法在每次调用next时只能调用一次。
    // 如果在迭代过程中,使用除了此方法以外的任何方式修改了底层集合,那么迭代器的行为是未指定的
    default void remove() {
        throw new UnsupportedOperationException("remove");
    }
    
    // 为每个剩余元素执行给定的操作,直到处理完所有元素或操作引发异常。
    // 如果指定了迭代的顺序,则按照迭代的顺序执行操作。
    // 操作引发的异常将被转发给调用者。
    default void forEachRemaining(Consumer<? super E> action) {
        Objects.requireNonNull(action);
        while (hasNext())
            action.accept(next());
    }
}

fail-fast mechanism

If, after the iterator is created, the structure of the collection has been modified in addition to other means other than their own methods remove and add iterator, the iterator will throw a ConcurrentModificationException. Therefore, in the face of concurrent modification, the iterator fails quickly and cleanly, rather than risk any time in the future an uncertain uncertain risk behavior.

ArrayList period of JavaDoc:

The iterators returned by this class's iterator and listIterator methods are fail-fast: if the list is structurally modified at any time after the iterator is created, in any way except through the iterator's own remove or add methods, the iterator will throw a ConcurrentModificationException. Thus, in the face of concurrent modification, the iterator fails quickly and cleanly, rather than risking arbitrary, non-deterministic behavior at an undetermined time in the future.

Note that the fail-fast behavior of an iterator cannot be guaranteed as it is, generally speaking, impossible to make any hard guarantees in the presence of unsynchronized concurrent modification. Fail-fast iterators throw ConcurrentModificationException on a best-effort basis. Therefore, it would be wrong to write a program that depended on this exception for its correctness: the fail-fast behavior of iterators should be used only to detect bugs.

This class is a member of the Java Collections Framework.

Note: faild-fast only detect whether there are other threads to modify the collection in the iterative process, because such collection itself is not thread-safe, so do not rely on it to ensure the correctness of the program.

Guess you like

Origin www.cnblogs.com/demojie/p/12596147.html