二十三种设计模式(十六)迭代器模式

迭代器模式,指的是在多个容器中,为了方便容器中元素的遍历从而让容器实现一个统一的接口。

目前Java已经提供了Iteratable去规范容器的迭代。它定义了迭代方法生成迭代器(Iterator);

Collection继承了该接口,使得所有实现Collection接口的容器都要去实现自己的迭代器,包括List,Map,Set,Vector等;

/**

* 迭代规范,所有实现该接口的实现类都需要实现里面的方法,主要就是生成自己的迭代器

*/

public interface Iterable<T> {

/**

* Returns an iterator over elements of type {@code T}.

*

* @return an Iterator.

*/

//实现类需要返回自己的迭代器

Iterator<T> iterator();

/**

* Performs the given action for each element of the {@code Iterable}

* 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.

* <p>

* The behavior of this method is unspecified if the action performs

* side-effects that modify the underlying source of elements, unless an

* overriding class has specified a concurrent modification policy.

*

* @implSpec

* <p>The default implementation behaves as if:

* <pre>{@code

* for (T t : this)

* action.accept(t);

* }</pre>

*

* @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<? super T> 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

* <em><a href="../util/Spliterator.html#binding">early-binding</a></em>

* spliterator from the iterable's {@code Iterator}. The spliterator

* inherits the <em>fail-fast</em> 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<T> spliterator() {

return Spliterators.spliteratorUnknownSize(iterator(), 0);

}

}

/**

* 迭代器

*/

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}.

* <p>

* 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, unless an overriding class has specified a

* concurrent modification policy.

* <p>

* The behavior of an iterator is unspecified if this method is called

* after a call to the {@link #forEachRemaining forEachRemaining} 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.

* <p>

* The behavior of an iterator is unspecified if the action modifies the

* collection in any way (even by calling the {@link #remove remove} method

* or other mutator methods of {@code Iterator} subtypes),

* unless an overriding class has specified a concurrent modification policy.

* <p>

* Subsequent behavior of an iterator is unspecified if the action throws an

* exception.

*

* @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提供的Iteratable接口定义了iterator()方法,使得实现类根据自身情况需要实现自己的迭代器,而迭代器核心就是两个方法,boolean hasNext();和E next();

而Collection<E> 接口又继承自Iterable,所以所有Collection接口的实现类都符合迭代器模式。并实现其中的hasNext();和E next();

下面是ArrayList自己的迭代器

/**

* ArrayList实现了List 而List实现了Collection

*/

public class ArrayList<E> extends AbstractList<E>

implements List<E>, RandomAccess, Cloneable, java.io.Serializable

{

public Iterator<E> iterator() {

return new Itr();

}

private class Itr implements Iterator<E> {

int cursor; // index of next element to return

int lastRet = -1; // index of last element returned; -1 if no such

int expectedModCount = modCount;

// prevent creating a synthetic constructor

Itr() {}

public boolean hasNext() {

return cursor != size;

}

@SuppressWarnings("unchecked")

public E next() {

checkForComodification();

int i = cursor;

if (i >= size)

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

checkForComodification();

try {

ArrayList.this.remove(lastRet);

cursor = lastRet;

lastRet = -1;

expectedModCount = modCount;

} catch (IndexOutOfBoundsException ex) {

throw new ConcurrentModificationException();

}

}

@Override

public void forEachRemaining(Consumer<? super E> action) {

Objects.requireNonNull(action);

final int size = ArrayList.this.size;

int i = cursor;

if (i < size) {

final Object[] es = elementData;

if (i >= es.length)

throw new ConcurrentModificationException();

for (; i < size && modCount == expectedModCount; i++)

action.accept(elementAt(es, i));

// update once at end to reduce heap write traffic

cursor = i;

lastRet = i - 1;

checkForComodification();

}

}

final void checkForComodification() {

if (modCount != expectedModCount)

throw new ConcurrentModificationException();

}

}

}

同样LinkedList,HashMap,TreeMap等常用数据结构也有自己的迭代器。

实际开发中很少使用自己开发的迭代器,但当新的数据结构容器产生,就一定要考虑到遍历问题,我们也可以实现Iterator接口自己写自己的迭代器。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值