迭代器模式,它提供一种按顺序访问集合/容器对象元素的方法,而又无需暴露集合内部表示。迭代器模式可以为不同的容器提供一致的遍历行为,而又不用关心容器内元素的组成结构。
实际日常开发中,几乎碰不到需要自己定义迭代器的场景,但我们需要了解这么一个设计模式,万一哪天真的需要自己定制实现一个数据结构及其对应的迭代器呢?
迭代器模式还是蛮简单的,像ArrayList就是一个经典的例子。
下面我自己实现迭代器模式
public class Book {
private String name;
public Book(String name) {
this.name = name;
}
@Override
public String toString() {
return "Book{" +
"name=‘" + name + ‘\‘‘ +
‘}‘;
}
}
//抽象迭代器
public interface Iterator<E> {
E next();
boolean hasNext();
}
//抽象容器
public interface IAggregate<E> {
boolean add(E ele);
boolean remove(E ele);
Iterator<E> iterator();
}
//自定义容器
public class BookAggregate implements IAggregate<Book>{
private List<Book> list = new ArrayList<>();
@Override
public boolean add(Book ele) {
return list.add(ele);
}
@Override
public boolean remove(Book ele) {
return list.remove(ele);
}
@Override
public Iterator<Book> iterator() {
return new Itr(list);
}
//迭代器实现
private class Itr implements Iterator<Book>{
private List<Book> list;
private int cursor = 0;
public Itr(List<Book> list) {
this.list = list;
}
@Override
public Book next() {
return list.get(this.cursor++);
}
@Override
public boolean hasNext() {
return this.cursor < this.list.size();
}
}
}
测试:
public static void main(String[] args) {
Book java = new Book("java");
Book html = new Book("spring");
Book docker = new Book("docker");
BookAggregate bookAggregate = new BookAggregate();
bookAggregate.add(java);
bookAggregate.add(html);
bookAggregate.add(docker);
Iterator<Book> iterator = bookAggregate.iterator();
while (iterator.hasNext()){
System.out.println(iterator.next());
}
}
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;
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();
}
}
.......
}
此外,ArrayList中对Itr进行了扩展,ListItr
private class ListItr extends Itr implements ListIterator<E> {
ListItr(int index) {
super();
cursor = index;
}
public boolean hasPrevious() {
return cursor != 0;
}
public int nextIndex() {
return cursor;
}
public int previousIndex() {
return cursor - 1;
}
@SuppressWarnings("unchecked")
public E previous() {
checkForComodification();
int i = cursor - 1;
if (i < 0)
throw new NoSuchElementException();
Object[] elementData = ArrayList.this.elementData;
if (i >= elementData.length)
throw new ConcurrentModificationException();
cursor = i;
return (E) elementData[lastRet = i];
}
....
}
增加了获取上一个元素的方法(借此可以逆向遍历)。我们可以通过ArrayList的listIterator方法去获取ListItr。
原文:https://www.cnblogs.com/wwjj4811/p/14220911.html