[Java 集合] 2. Iterator 接口


一、概述

Iterator是 java.util 包下定义的一个接口,表示迭代器。如下:
在这里插入图片描述

Java 8 中已知的子接口包括:

  • ListIterator
  • PrimitiveIterator<T,T_CONS>
  • PrimitiveIterator.OfDouble
  • PrimitiveIterator.OfInt
  • PrimitiveIterator.OfLong
  • XMLEventReader

说明: 其中 PrimitiveIterator<T,T_CONS> 是原始迭代器,T 表示 PrimitiveIterator 返回的元素类型,T_CONS 表示 T 的原始消费者 Consumer,PrimitiveIterator.OfDouble、PrimitiveIterator.OfInt、PrimitiveIterator.OfLong 都是 PrimitiveIterator接口的静态内部接口(static interface); XMLEventReader 是 javax.xml.stream 包中定义的一个接口,这两类接口不是我们《Java Collections》的总结重点,这里重点总结下 Iterator 接口和 ListIterator 接口。


二、Iterator

从API中可以看出 Iterator 包含 4 个方法,分别是 hasNext()、next()、remove()、forEachRemaining(Consumer<? super E> action),其中 remove、forEachRemaining 方法是 default 方法,这些个方法都比较简单。

2.1 haseNext() 方法

判断当前迭代器是否包含下一个元素,如果包含返回 true,否则返回false;

/**
 * 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();

2.2 next() 方法

获取当前迭代器的下一个元素,如果下一个元素为空则抛出 NoSuchElementException。

/**
 * 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();

2.3 remove() 方法

移除底层集合的迭代器中的最后一个元素。

注意点:

  1. 这个方法需要底层的集合类重写该方法,否则执行默认方法会抛出 UnsupportedOperationException。
  2. 如果调用 remove() 方法之前没有被调用 next() 方法,或者调用一次next() 方法之后连续调用了2次remove() 方法,则会抛出 IllegalStateException。很好理解,因为该方法会删除当前迭代器迭代的最后一个元素,如果最后一个元素不存在,那么肯定会抛出 IllegalStateException 异常。
/**
 * 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");
}

2.4 forEachRemaining(Consumer<? super E> action) 方法

遍历消费完剩余的元素,接收一个函数式接口 Consumer。这个方法也比较简单,建议经常用。


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

三、ListIterator

从 Iterator 的 API 中我们也可以得到一个很重要的信息,那就是 Iterator 只能正向操作,也只能遍历一次,遍历完一次之后就不能再遍历了。

但是 ListIterator 的 API 会告诉我们,它可以双向遍历(既可以正向遍历、也可以反向遍历),ListIterator 是一个双向迭代器,除此之外,它还可以添加和修改底层的集合元素。

在这里插入图片描述

说明: 从API中我们可以知道 ListIterator 继承了父接口的四个方法,除此之外,还新增了hasPrevious()、previous()、nextIndex()、previousIndex()、set(E e)、add(E e)方法。这些方法都比较简单,分别是判断迭代器是否存在上一个元素、获取上一个元素、获取下一个元素的索引、获取上一个元素的索引、设置当前迭代的元素值、添加一个元素的值,都比较简单,就不总结了。


四、迭代器的性能

在数组结构的集合中:普通for循环 > foreach ≈ iterator
在LinkList结构的集合中:普通for循环 < foreach ≈ iterator

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值