Bootstrap

Iterator 迭代器设计模式

一、Iterator 迭代器设计模式
    迭代器设计模式的作用可以提供一种方法顺序访问一个聚合对象中各个元素,而又不暴露该对象的内部表示。
    迭代器模式有三个重要作用:
    1、支持以不同的方式遍历集合
        根据我们生成的迭代器的实现不同,可以采用不同的遍历方式。
    2、迭代器简化了集合接口。有了迭代器的遍历接口,集合不再需要类似的接口,也不再关注具体的遍历实现。
    3、在同一集合中可以有多个遍历。每个迭代器保持着自己的遍历状态,所以一个集合同时可以进行多个遍历。
二、示例程序:    
2.1 类和接口一览
名字     说明
Stack     集合类
Iterable     可迭代接口
MyArrayStack   集合类的具体实现
Iterator     迭代器接口
MyArrayStackIterator    迭代器的具体实现
2.2 Iterator 接口
    Java中已经给我们提供好了Iterator接口
    
   
   
  1. public interface Iterator<E> {
  2. boolean hasNext();
  3. E next();
  4. default void remove() {
  5. throw new UnsupportedOperationException("remove");
  6. }
  7. default void forEachRemaining(Consumer<? super E> action) {
  8. Objects.requireNonNull(action);
  9. while (hasNext())
  10. action.accept(next());
  11. }
  12. }
    该接口主要使用的是两个方法,一个是判断是否有下一个元素hasNext(),另一个是获取下一个元素next()方法。hasNext()方法是循环迭代的终止方法,而next()方法是获取集合元素的方法,根据next()方法的实现不同,我们可以实现不同的迭代器。
2.2 Iterable 接口
    同样Java已经给我们提供好了
    
    
  1. public interface Iterable<T> {
  2. Iterator<T> iterator();
  3. default void forEach(Consumer<? super T> action) {
  4. Objects.requireNonNull(action);
  5. for (T t : this) {
  6. action.accept(t);
  7. }
  8. }
  9. default Spliterator<T> spliterator() {
  10. return Spliterators.spliteratorUnknownSize(iterator(), 0);
  11. }
  12. }
    Iterable 表示结合能否进行foreach 遍历,主要关注 方法是iterator(),获取迭代器。
2.3 Stack 集合接口
    
    
    
  1. public interface Stack<Item> {
  2. Item pop();//弹出一个最后加入的元素
  3. void push(Item item);//添加元素
  4. boolean isEmpty();
  5. int size();//当前栈的元素个数
  6. }
    这个接口是下压栈的集合接口,我们提供添加元素,移除元素,判断集合是否为空,以及集合大小等方法。
2.4 MyArrayStack类
    该类是下压栈的数组实现方式。
    
     
     
  1. public class MyArrayStack<Item> implements Stack<Item>,Iterable<Item>{
  2. Item[] items = null;//集合的底层数组实现
  3. int N = 0;//当前集合容量
  4. public MyArrayStack(int num){
  5. items = (Item[]) new Object[num];//java不支持泛型数组,可以使用强转的方式实现
  6. }
  7. public Item pop() {
  8. if(N == 0){
  9. return null;
  10. }
  11. Item item = items[--N];
  12. items[N] = null;//防止出现对象游离,因为数组还保存着对元素的引用,java不会回收该对象
  13. if(N == items.length/4){
  14. resize(items.length/2);
  15. }
  16. return item;
  17. }
  18. public void push(Item item) {
  19. if(N == items.length){
  20. resize(2*items.length);
  21. }
  22. items[N++] = item;
  23. }
  24. public boolean isEmpty() {
  25. return N==0;
  26. }
  27. public int size() {
  28. return N;
  29. }
  30. //实现自动扩容的方式
  31. private void resize(int num){
  32. Item[] temp = (Item[]) new Object[num];
  33. for(int i = 0;i<N ; i++){
  34. temp[i] = items[i];
  35. }
  36. items = temp;
  37. }
  38. public Iterator<Item> iterator() {
  39. return new MyArrayStackIterator();
  40. }
  41. private class MyArrayStackIterator implements Iterator<Item>{
  42. private int i = N;
  43. public boolean hasNext() {
  44. return i>0;
  45. }
  46. public Item next() {
  47. return items[--i];
  48. }
  49. }
  50. }
    需要注意的是该类有内部类 MyArrayStackIterator 也即迭代器的具体实现类。
 2.5 测试方法
        
      
      
  1. public static void main(String[] args) {
  2. MyArrayStack<String> stacks = new MyArrayStack<>(10);
  3. stacks.push("1");
  4. stacks.push("2");
  5. for(String s : stacks){
  6. System.out.println(s);
  7. }
  8. }


   三、Iterator 类图

 四、Iterator模式中的角色
4.1 Iterator 迭代器
    该角色负责定义按顺序逐个遍历元素的接口。
4.2 ConcreteIterator 具体的迭代器
    上述实例中MyArrayStackIterator扮演该角色,负责实现Iterator角色中所定义的接口。
4.3 Aggregate 集合
    该角色负责定义集合接口,Stack扮演该角色
4.4 ConcreteAggregate 具体的集合
    负责实现Aggregate定义的接口。

;