Iterator

Jan 18, 2018


JDK1.8对Iterator接口进行了一些修改,现在就来看一下。

源码

/**
 * An iterator over a collection.  {@code Iterator} takes the place of
 * {@link Enumeration} in the Java Collections Framework.  Iterators
 * differ from enumerations in two ways:
 *
 * <ul>
 *      <li> Iterators allow the caller to remove elements from the
 *           underlying collection during the iteration with well-defined
 *           semantics.
 *      <li> Method names have been improved.
 * </ul>
 *
 * <p>This interface is a member of the
 * <a href="{@docRoot}/../technotes/guides/collections/index.html">
 * Java Collections Framework</a>.
 *
 * @param <E> the type of elements returned by this iterator
 *
 * @author  Josh Bloch
 * @see Collection
 * @see ListIterator
 * @see Iterable
 * @since 1.2
 */
public interface Iterator<E> {
    /**
     * Returns {@code true} if the iteration has more elements.
     * (In other words, returns {@code true} if {@link #next} would
     * return an element rather than throwing an exception.)
     *
     * @return {@code true} if the iteration has more elements
     */
    boolean hasNext();

    /**
     * Returns the next element in the iteration.
     *
     * @return the next element in the iteration
     * @throws NoSuchElementException if the iteration has no more elements
     */
    E next();

    /**
     * Removes from the underlying collection the last element returned
     * by this iterator (optional operation).  This method can be called
     * only once per call to {@link #next}.  The behavior of an iterator
     * is unspecified if the underlying collection is modified while the
     * iteration is in progress in any way other than by calling this
     * method.
     *
     * @implSpec
     * The default implementation throws an instance of
     * {@link UnsupportedOperationException} and performs no other action.
     *
     * @throws UnsupportedOperationException if the {@code remove}
     *         operation is not supported by this iterator
     *
     * @throws IllegalStateException if the {@code next} method has not
     *         yet been called, or the {@code remove} method has already
     *         been called after the last call to the {@code next}
     *         method
     */
    default void remove() {
        throw new UnsupportedOperationException("remove");
    }

    /**
     * Performs the given action for each remaining element until all elements
     * have been processed or the action throws an exception.  Actions are
     * performed in the order of iteration, if that order is specified.
     * Exceptions thrown by the action are relayed to the caller.
     *
     * @implSpec
     * <p>The default implementation behaves as if:
     * <pre>{@code
     *     while (hasNext())
     *         action.accept(next());
     * }</pre>
     *
     * @param action The action to be performed for each element
     * @throws NullPointerException if the specified action is null
     * @since 1.8
     */
    default void forEachRemaining(Consumer<? super E> action) {
        Objects.requireNonNull(action);
        while (hasNext())
            action.accept(next());
    }
}

翻译

/**
 * 集合上的迭代器。迭代器替换Java集合框架中的枚举。
 * 迭代器和枚举的不同体现在两方面:
 * 1. 迭代器允许调用者在迭代过程中从定义良好的语义中删除底层集合中的元素
 * 2. 方法名称已得到改进
 * 
 *	这个接口是Java集合框架中的一个成员。
 *
 * @param <E> 该迭代器返回的元素类型
 *
 * @author  Josh Bloch
 * @see Collection
 * @see ListIterator
 * @see Iterable
 * @since 1.2
 */
public interface Iterator<E> {
    /**
     * 如果迭代中有下一个元素,则返回 true
     * 就是说,如果返回true,则next方法会返回一个元素而不是抛出异常
     *
     * @return {@code true} 如果迭代中有下一个元素
     */
    boolean hasNext();

    /**
     * 返回迭代中的下一个元素
     *
     * @return 迭代中的下一个元素
     * @throws NoSuchElementException 如果迭代中没有下一个元素
     */
    E next();

    /**
     * 从底层集合中删除迭代器返回的最后一个元素(可选操作)。
     * 该方法每次调用next方法只能被调用一次。
     * 如果底层集合在迭代过程中被除了该方法之外的任何方法修改,那么迭代器的行为是不确定的。
     *
     * @implSpec 默认的实现会抛出一个UnsupportedOperationException异常的实例,而没有执行其他任何行为。
     * @throws UnsupportedOperationException 如果remove操作不被当前迭代器支持
     *
     * @throws IllegalStateException 如果next方法还没有被调用,或者remove方法在最后一次调用next方法之后被调用
     */
    default void remove() {
        throw new UnsupportedOperationException("remove");
    }

    /**
     * 对每个剩余的元素执行给定的操作,直到所有元素都被处理或者抛出异常为止
     * 如果指定了顺序,则按迭代顺序执行操作
     * 操作抛出的异常将被反馈给调用者
     *
     * @implSpec 默认的实现行为如下:
     *     while (hasNext())
     *         action.accept(next());
     *
     * @param action 对每个元素执行的操作
     * @throws NullPointerException 如果指定的操作为null
     * @since 1.8
     */
    default void forEachRemaining(Consumer<? super E> action) {
        Objects.requireNonNull(action);
        while (hasNext())
            action.accept(next());
    }
}

摘要

  1. 在原来基础上增加了forEachRemaining方法

实例

定义一个对象:

public class Student {
	private String name;

	public Student(String name) {
		this.name = name;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	@Override
	public String toString() {
		return "Student [name=" + name + "]";
	}
}

实例1:

List<Student> b = new ArrayList<Student>(
		Arrays.asList(new Student("lin"), new Student("chen"), new Student("remove")));
b.forEach(s -> System.out.print(s.toString()));
System.out.println();
Iterator<Student> iterator = b.iterator();
while (iterator.hasNext()) {
	Student next = iterator.next();
	if (next.getName().startsWith("r")) {
		iterator.remove();
	}
}
b.forEach(s -> System.out.print(s.toString()));

输出结果为:
Student [name=lin]Student [name=chen]Student [name=remove]
Student [name=lin]Student [name=chen]

实例2:

List<Student> b = Arrays.asList(new Student("lin"), new Student("chen"));
b.forEach(s -> System.out.println(s.toString()));
b.iterator().forEachRemaining(s -> s.setName(s.getName() + "-baby"));
b.forEach(s -> System.out.println(s.toString()));

输出结果为:
Student [name=lin]
Student [name=chen]
Student [name=lin-baby]
Student [name=chen-baby]