Java中Iterator和Iterable

对Collection大家族的遍历,常用两种格式,一种是foreach遍历,另外一种是迭代器遍历。之前这两种遍历方式一直用只知道有一个区别,就是foreach是增强for循环,在java1.5后才有的,用于对集合的遍历不能修改元素,否则遍历会出错;而迭代器Iterator(java.util.iterator)呢,能对集合进行修改;

public interface Iterator {
    /**
     * 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
     * 

The default implementation behaves as if: *

{@code
     *     while (hasNext())
     *         action.accept(next());
     * }
* * @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 action) { Objects.requireNonNull(action); while (hasNext()) action.accept(next()); } }

 

查看foreach(Think in Java 241-foreach与迭代器)可知,foreach语法能工作,是因为java1.5后引入了新的接口Iterable(java.lang.Iterable),这个接口提供一个方法iterator(),这个方法会返回一个iterator对象;所以,在实现这个接口的具体类里比如说ArrayList类中,必须要重写抽象方法【iterator()】,通过该方法就会持有一个含有该类型的iterator迭代器对象,。而且可以看见java的开发文档,collection集合大家族中能实现foreach遍历,简化代码的原因就是都继承自Iterable,而在Iterable的源码里可以看到,有一个默认的foreach方法,所以能实现迭代。Iterable源码如下所示:

public interface Iterable {
    /**
     * Returns an iterator over elements of type {@code T}.
     *
     * @return an Iterator.
     */
    Iterator iterator();

    /**
     * Performs the given action for each element of the {@code Iterable}
     * until all elements have been processed or the action throws an
     * exception.  Unless otherwise specified by the implementing class,
     * actions are performed in the order of iteration (if an iteration order
     * is specified).  Exceptions thrown by the action are relayed to the
     * caller.
     *
     * @implSpec
     * 

The default implementation behaves as if: *

{@code
     *     for (T t : this)
     *         action.accept(t);
     * }
* * @param action The action to be performed for each element * @throws NullPointerException if the specified action is null * @since 1.8 */ default void forEach(Consumer action) { Objects.requireNonNull(action); for (T t : this) { action.accept(t); } } /** * Creates a {@link Spliterator} over the elements described by this * {@code Iterable}. * * @implSpec * The default implementation creates an * early-binding * spliterator from the iterable's {@code Iterator}. The spliterator * inherits the fail-fast properties of the iterable's iterator. * * @implNote * The default implementation should usually be overridden. The * spliterator returned by the default implementation has poor splitting * capabilities, is unsized, and does not report any spliterator * characteristics. Implementing classes can nearly always provide a * better implementation. * * @return a {@code Spliterator} over the elements described by this * {@code Iterable}. * @since 1.8 */ default Spliterator spliterator() { return Spliterators.spliteratorUnknownSize(iterator(), 0); } }

总结来说就是,Iterator接口的作用是迭代器,从所属的java包的名字就可以看出来(java.utils.*),是一个工具类,能对集合的存储内容进行更改,而Iterable接口的作用了是实现简单遍历,是一种结构(java.lang.*),不仅如此,实现了Iterable的接口的类,还可以通过它的iterator()方法获取到iterator迭代器对象,从而也能实现遍历与修改。而且从java中collection大家族的继承关系树可以看到,都是继承自Iterable接口,从而既能实现简化遍历,又能修改集合内容。

你可能感兴趣的:(java)