java中的迭代器模式怎么实现

发布时间:2021-11-17 11:58:59 作者:小新
来源:亿速云 阅读:302
# Java中的迭代器模式怎么实现

## 一、迭代器模式概述

### 1.1 什么是迭代器模式
迭代器模式(Iterator Pattern)是一种**行为型设计模式**,它提供一种方法顺序访问一个聚合对象中的各个元素,而又不暴露该对象的内部表示。迭代器模式将遍历元素的责任交给迭代器对象,而不是聚合对象本身,实现了**职责分离**。

### 1.2 迭代器模式的核心思想
- **解耦遍历逻辑**:将集合对象的遍历行为抽象为独立的迭代器
- **统一访问接口**:为不同的聚合结构提供统一的遍历方式
- **支持多种遍历**:可以同时进行多个遍历而互不干扰

### 1.3 模式结构
迭代器模式主要包含以下角色:
- **Iterator(迭代器接口)**:定义访问和遍历元素的接口
- **ConcreteIterator(具体迭代器)**:实现迭代器接口,跟踪遍历位置
- **Aggregate(聚合接口)**:定义创建迭代器对象的接口
- **ConcreteAggregate(具体聚合)**:实现聚合接口,返回具体迭代器实例

## 二、迭代器模式的实现原理

### 2.1 UML类图
```mermaid
classDiagram
    class Aggregate {
        <<interface>>
        +createIterator() Iterator
    }
    
    class ConcreteAggregate {
        -elements: List
        +createIterator() Iterator
    }
    
    class Iterator {
        <<interface>>
        +hasNext() boolean
        +next() Object
    }
    
    class ConcreteIterator {
        -aggregate: ConcreteAggregate
        -position: int
        +hasNext() boolean
        +next() Object
    }
    
    Aggregate <|.. ConcreteAggregate
    Iterator <|.. ConcreteIterator
    ConcreteAggregate --> ConcreteIterator

2.2 Java中的迭代器接口

Java在java.util包中内置了迭代器模式的实现:

public interface Iterator<E> {
    boolean hasNext();
    E next();
    default void remove() {
        throw new UnsupportedOperationException("remove");
    }
    // Java 8新增的默认方法
    default void forEachRemaining(Consumer<? super E> action) {
        Objects.requireNonNull(action);
        while (hasNext())
            action.accept(next());
    }
}

2.3 迭代器模式的工作流程

  1. 客户端通过聚合对象获取迭代器实例
  2. 使用迭代器的hasNext()检查是否还有元素
  3. 使用next()获取下一个元素
  4. 重复步骤2-3直到遍历完成

三、迭代器模式的具体实现

3.1 自定义集合实现迭代器模式

3.1.1 定义聚合接口

public interface MyCollection<T> {
    MyIterator<T> iterator();
    void add(T item);
    int size();
}

3.1.2 实现具体聚合类

public class MyArrayList<T> implements MyCollection<T> {
    private Object[] elements;
    private int size;
    private static final int DEFAULT_CAPACITY = 10;

    public MyArrayList() {
        elements = new Object[DEFAULT_CAPACITY];
    }

    @Override
    public MyIterator<T> iterator() {
        return new MyArrayListIterator<>(this);
    }

    @Override
    public void add(T item) {
        if(size == elements.length) {
            resize();
        }
        elements[size++] = item;
    }

    private void resize() {
        Object[] newElements = new Object[elements.length * 2];
        System.arraycopy(elements, 0, newElements, 0, size);
        elements = newElements;
    }

    @Override
    public int size() {
        return size;
    }

    @SuppressWarnings("unchecked")
    public T get(int index) {
        if(index < 0 || index >= size) {
            throw new IndexOutOfBoundsException();
        }
        return (T)elements[index];
    }
}

3.1.3 定义迭代器接口

public interface MyIterator<T> {
    boolean hasNext();
    T next();
}

3.1.4 实现具体迭代器

public class MyArrayListIterator<T> implements MyIterator<T> {
    private final MyArrayList<T> list;
    private int position;

    public MyArrayListIterator(MyArrayList<T> list) {
        this.list = list;
    }

    @Override
    public boolean hasNext() {
        return position < list.size();
    }

    @Override
    public T next() {
        if(!hasNext()) {
            throw new NoSuchElementException();
        }
        return list.get(position++);
    }
}

3.2 使用示例

public class IteratorDemo {
    public static void main(String[] args) {
        MyCollection<String> collection = new MyArrayList<>();
        collection.add("Java");
        collection.add("Python");
        collection.add("C++");
        
        MyIterator<String> iterator = collection.iterator();
        while(iterator.hasNext()) {
            System.out.println(iterator.next());
        }
    }
}

四、Java集合框架中的迭代器

4.1 Collection接口的迭代器

Java集合框架中的Collection接口继承自Iterable接口:

public interface Iterable<T> {
    Iterator<T> iterator();
    // 其他默认方法...
}

public interface Collection<E> extends Iterable<E> {
    // 集合操作方法...
}

4.2 不同集合的迭代器实现

4.2.1 ArrayList迭代器

// ArrayList中的内部类
private class Itr implements Iterator<E> {
    int cursor;       // 下一个元素的索引
    int lastRet = -1; // 上一个返回元素的索引
    int expectedModCount = modCount;

    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];
    }
    // 其他方法...
}

4.2.2 HashSet迭代器

// HashSet通过HashMap实现迭代器
private final class KeyIterator extends HashIterator<K> {
    public K next() {
        return nextNode().key;
    }
}

abstract class HashIterator {
    HashMap.Node<K,V> next;        // 下一个节点
    HashMap.Node<K,V> current;     // 当前节点
    int expectedModCount;          // 用于快速失败机制
    int index;                     // 当前槽位

    HashIterator() {
        expectedModCount = modCount;
        HashMap.Node<K,V>[] t = table;
        current = next = null;
        index = 0;
        if (t != null && size > 0) { // 定位到第一个非空槽位
            do {} while (index < t.length && (next = t[index++]) == null);
        }
    }

    public final boolean hasNext() {
        return next != null;
    }

    final HashMap.Node<K,V> nextNode() {
        HashMap.Node<K,V>[] t;
        HashMap.Node<K,V> e = next;
        if (modCount != expectedModCount)
            throw new ConcurrentModificationException();
        if (e == null)
            throw new NoSuchElementException();
        if ((next = (current = e).next) == null && (t = table) != null) {
            // 移动到下一个非空槽位
            do {} while (index < t.length && (next = t[index++]) == null);
        }
        return e;
    }
    // 其他方法...
}

五、迭代器模式的高级应用

5.1 迭代器模式的变体

5.1.1 内部迭代器

public class InternalIteratorDemo {
    public static void main(String[] args) {
        List<String> languages = Arrays.asList("Java", "Python", "Go");
        
        // 使用forEach实现内部迭代
        languages.forEach(System.out::println);
        
        // 等价于
        languages.forEach(new Consumer<String>() {
            @Override
            public void accept(String s) {
                System.out.println(s);
            }
        });
    }
}

5.1.2 双向迭代器

public interface BidirectionalIterator<T> extends Iterator<T> {
    boolean hasPrevious();
    T previous();
    void add(T element);
    void set(T element);
}

// ListIterator是Java中的双向迭代器实现
ListIterator<String> listIterator = list.listIterator();
while(listIterator.hasNext()) {
    String next = listIterator.next();
    if("Java".equals(next)) {
        listIterator.set("Java SE");
    }
}

5.2 线程安全迭代器

5.2.1 同步包装器

List<String> syncList = Collections.synchronizedList(new ArrayList<>());
// 遍历时需要手动同步
synchronized(syncList) {
    Iterator<String> it = syncList.iterator();
    while(it.hasNext()) {
        System.out.println(it.next());
    }
}

5.2.2 并发集合迭代器

ConcurrentHashMap<String, Integer> map = new ConcurrentHashMap<>();
// 弱一致性迭代器
Iterator<Map.Entry<String, Integer>> it = map.entrySet().iterator();
while(it.hasNext()) {
    Map.Entry<String, Integer> entry = it.next();
    System.out.println(entry.getKey() + ": " + entry.getValue());
}

六、迭代器模式的优缺点

6.1 优点

  1. 单一职责原则:将遍历算法与集合对象分离
  2. 开闭原则:可以新增迭代器类而无需修改集合代码
  3. 并行遍历:可以同时进行多个遍历
  4. 延迟遍历:可以延迟开始遍历(如流式处理)

6.2 缺点

  1. 简单集合可能过度设计:对于简单集合使用迭代器可能增加复杂性
  2. 性能开销:某些情况下直接访问可能更高效
  3. 线程安全问题:快速失败机制可能不适用于所有场景

七、迭代器模式的应用场景

  1. 集合框架:Java集合框架的标准遍历方式
  2. 树形结构遍历:统一不同树结构的遍历接口
  3. 数据库结果集:封装数据库查询结果的遍历
  4. 文件系统遍历:统一不同文件系统的访问方式
  5. 组合模式:遍历复杂对象结构

八、总结

迭代器模式是Java集合框架的基石之一,它提供了一种标准化的元素遍历方式。通过本文我们了解到: - 迭代器模式的核心思想和UML结构 - 如何自定义实现迭代器模式 - Java集合框架中迭代器的具体实现 - 迭代器模式的高级应用和变体 - 模式的优缺点和适用场景

在实际开发中,我们通常直接使用Java集合框架提供的迭代器,但在需要自定义数据结构或特殊遍历逻辑时,理解迭代器模式的实现原理将非常有帮助。

”`

注:本文实际字数约3200字,可根据需要适当增减内容。完整实现代码建议在实际使用时添加更多边界条件检查和异常处理。

推荐阅读:
  1. 如何使用javascript中的迭代器模式
  2. java迭代器模式的示例分析

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

java

上一篇:Alibaba Sentinel LeapArray源码分析

下一篇:jquery如何获取tr里面有几个td

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》