在软件开发中,我们经常需要处理各种集合对象——数组、列表、树形结构等等。想象一下,如果你有一个复杂的集合结构,比如一个多层嵌套的树形菜单,而你需要遍历其中的每一个元素。最直接的做法可能是直接暴露集合的内部结构,让客户端代码直接访问。但这样做的后果是什么?
首先,客户端代码会与集合的具体实现紧密耦合。如果有一天你需要更换集合的实现方式(比如从数组改为链表),所有使用这个集合的客户端代码都需要修改。其次,不同的集合结构可能需要不同的遍历方式,客户端代码需要了解这些细节才能正确遍历。最后,如果你需要同时支持多种遍历方式(比如正序、逆序、按条件过滤等),代码会变得非常混乱。
这就是迭代器模式要解决的问题。它提供了一种方法,可以顺序访问一个聚合对象中的各个元素,而又不暴露该对象的内部表示。就像你去图书馆找书,你不需要知道书是怎么存放的(是按分类号排列还是按作者姓氏排列),你只需要知道如何使用目录系统(迭代器)就能找到你想要的书。
迭代器模式主要涉及以下几个角色:
让我们用一个简单的例子来说明这些角色如何协作。假设我们有一个书架(BookShelf)类,它包含多本书(Book),我们想遍历这些书:
code复制// 聚合接口
interface Aggregate {
Iterator createIterator();
}
// 具体聚合
class BookShelf implements Aggregate {
private Book[] books;
private int last = 0;
public BookShelf(int maxsize) {
this.books = new Book[maxsize];
}
public Book getBookAt(int index) {
return books[index];
}
public void appendBook(Book book) {
this.books[last] = book;
last++;
}
public int getLength() {
return last;
}
@Override
public Iterator createIterator() {
return new BookShelfIterator(this);
}
}
// 迭代器接口
interface Iterator {
boolean hasNext();
Object next();
}
// 具体迭代器
class BookShelfIterator implements Iterator {
private BookShelf bookShelf;
private int index;
public BookShelfIterator(BookShelf bookShelf) {
this.bookShelf = bookShelf;
this.index = 0;
}
@Override
public boolean hasNext() {
return index < bookShelf.getLength();
}
@Override
public Object next() {
Book book = bookShelf.getBookAt(index);
index++;
return book;
}
}
// 客户端使用
public class Main {
public static void main(String[] args) {
BookShelf bookShelf = new BookShelf(4);
bookShelf.appendBook(new Book("Design Patterns"));
bookShelf.appendBook(new Book("Clean Code"));
bookShelf.appendBook(new Book("Refactoring"));
bookShelf.appendBook(new Book("Domain-Driven Design"));
Iterator it = bookShelf.createIterator();
while (it.hasNext()) {
Book book = (Book)it.next();
System.out.println(book.getName());
}
}
}
在这个例子中,BookShelf是具体聚合,BookShelfIterator是具体迭代器。客户端代码只需要通过Iterator接口来遍历集合,完全不需要知道BookShelf内部是如何存储书籍的(这里用的是数组,但可以随时改为其他结构而不影响客户端代码)。
迭代器模式的一个强大之处在于可以轻松支持多种遍历方式。比如,我们可以为同一个集合提供正序、逆序甚至按特定条件过滤的迭代器。
让我们扩展前面的BookShelf例子,添加一个逆序迭代器:
code复制// 逆序迭代器
class ReverseBookShelfIterator implements Iterator {
private BookShelf bookShelf;
private int index;
public ReverseBookShelfIterator(BookShelf bookShelf) {
this.bookShelf = bookShelf;
this.index = bookShelf.getLength() - 1;
}
@Override
public boolean hasNext() {
return index >= 0;
}
@Override
public Object next() {
Book book = bookShelf.getBookAt(index);
index--;
return book;
}
}
// 修改BookShelf类,添加创建逆序迭代器的方法
class BookShelf implements Aggregate {
// ... 之前的代码不变 ...
public Iterator createReverseIterator() {
return new ReverseBookShelfIterator(this);
}
}
// 客户端使用
public class Main {
public static void main(String[] args) {
BookShelf bookShelf = new BookShelf(4);
// ... 添加书籍的代码不变 ...
System.out.println("正序遍历:");
Iterator it = bookShelf.createIterator();
while (it.hasNext()) {
Book book = (Book)it.next();
System.out.println(book.getName());
}
System.out.println("\n逆序遍历:");
Iterator reverseIt = bookShelf.createReverseIterator();
while (reverseIt.hasNext()) {
Book book = (Book)reverseIt.next();
System.out.println(book.getName());
}
}
}
迭代器可以分为两种类型:
Java 8引入的forEach方法就是一种内部迭代器:
code复制bookShelf.forEach(book -> System.out.println(book.getName()));
内部迭代器的优点是使用更简洁,但灵活性不如外部迭代器。外部迭代器可以让客户端控制迭代过程,比如在特定条件下提前终止迭代。
在多线程环境下使用迭代器时需要注意线程安全问题。如果在迭代过程中集合被另一个线程修改,可能会导致不可预期的行为。Java的集合框架中就有"快速失败"(fail-fast)迭代器的概念,当检测到集合在迭代过程中被修改时会抛出ConcurrentModificationException。
如果你需要在多线程环境下使用迭代器,可以考虑以下方案:
Java的集合框架(Collection Framework)是迭代器模式的最佳实践之一。所有集合类都实现了Iterable接口,该接口定义了一个iterator()方法返回Iterator实例。这使得我们可以用统一的方式遍历各种不同的集合:
code复制List<String> list = Arrays.asList("A", "B", "C");
Iterator<String> it = list.iterator();
while (it.hasNext()) {
System.out.println(it.next());
}
Set<Integer> set = new HashSet<>(Arrays.asList(1, 2, 3));
Iterator<Integer> setIt = set.iterator();
while (setIt.hasNext()) {
System.out.println(setIt.next());
}
从Java 5开始,还可以使用更简洁的for-each语法,它背后也是使用迭代器:
code复制for (String item : list) {
System.out.println(item);
}
在JDBC中,ResultSet对象本质上也是一个迭代器,它提供了next()方法来遍历查询结果:
code复制Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery("SELECT id, name FROM users");
while (rs.next()) {
int id = rs.getInt("id");
String name = rs.getString("name");
System.out.println(id + ": " + name);
}
文件系统的遍历是另一个典型的迭代器模式应用场景。Java NIO中的Files.walk()方法返回一个Stream
code复制try (Stream<Path> paths = Files.walk(Paths.get("/path/to/dir"))) {
paths.filter(Files::isRegularFile)
.forEach(System.out::println);
}
对于树形结构,迭代器模式可以隐藏复杂的遍历算法(如深度优先、广度优先)。例如,对DOM树的遍历:
code复制// 伪代码示例
interface TreeNode {
Iterator<TreeNode> createDepthFirstIterator();
Iterator<TreeNode> createBreadthFirstIterator();
}
class XmlElement implements TreeNode {
// 实现细节...
@Override
public Iterator<TreeNode> createDepthFirstIterator() {
return new DepthFirstIterator(this);
}
@Override
public Iterator<TreeNode> createBreadthFirstIterator() {
return new BreadthFirstIterator(this);
}
}
// 客户端使用
TreeNode root = parseXmlDocument();
Iterator<TreeNode> it = root.createDepthFirstIterator();
while (it.hasNext()) {
TreeNode node = it.next();
processNode(node);
}
迭代器模式特别适用于以下场景:
组合模式常和迭代器模式一起使用。组合模式创建的树形结构通常需要遍历,而迭代器模式可以优雅地解决这个问题。例如,在GUI组件树、文件系统等场景中,我们经常同时使用这两种模式。
注意我们之前的BookShelf例子中,createIterator()就是一个工厂方法。迭代器模式经常使用工厂方法来创建适当的迭代器实例。
访问者模式也可以用于遍历复杂结构,但它更关注对元素的操作,而迭代器模式更关注遍历本身。两者可以结合使用:先用迭代器遍历,再用访问者对每个元素执行操作。
现代编程语言通常对迭代器模式有很好的支持,应该优先使用这些内置机制:
在一些支持生成器(Generator)的语言中(如Python、JavaScript、C#),可以用更简洁的方式实现迭代器:
python复制# Python生成器示例
def count_down(num):
while num > 0:
yield num
num -= 1
for n in count_down(5):
print(n) # 输出 5, 4, 3, 2, 1
对于不可变集合,迭代器可以更高效地实现,因为不需要考虑并发修改的问题。例如,可以直接预计算迭代路径或共享内部状态。
对于需要释放资源的迭代器(如数据库查询结果集),考虑实现Closeable/AutoCloseable接口:
code复制class DatabaseRecordIterator implements Iterator<Record>, AutoCloseable {
private ResultSet rs;
private boolean hasNext;
public DatabaseRecordIterator(ResultSet rs) {
this.rs = rs;
advance();
}
private void advance() {
hasNext = rs.next();
}
@Override
public boolean hasNext() {
return hasNext;
}
@Override
public Record next() {
if (!hasNext) throw new NoSuchElementException();
Record record = convert(rs);
advance();
return record;
}
@Override
public void close() throws Exception {
rs.close();
}
}
// 使用try-with-resources确保迭代器被正确关闭
try (DatabaseRecordIterator it = new DatabaseRecordIterator(rs)) {
while (it.hasNext()) {
process(it.next());
}
}
这是一个常见陷阱。大多数集合不允许在迭代过程中被修改(除了通过迭代器自己的remove()方法)。解决方案:
总是考虑集合为空的情况。好的迭代器实现应该能正确处理空集合,hasNext()立即返回false。
对于非常大的数据集(如数据库表),考虑:
测试迭代器时,确保覆盖以下情况:
Java 8引入的Stream API可以看作是对迭代器模式的增强,支持更丰富的操作(过滤、映射、归约等):
code复制List<String> names = Arrays.asList("Alice", "Bob", "Charlie");
names.stream()
.filter(name -> name.length() > 4)
.map(String::toUpperCase)
.forEach(System.out::println);
C#的LINQ提供了类似的强大功能:
csharp复制var names = new List<string> {"Alice", "Bob", "Charlie"};
var result = names.Where(name => name.Length > 4)
.Select(name => name.ToUpper());
foreach (var name in result) {
Console.WriteLine(name);
}
ES6引入了更正式的迭代器协议,任何实现了[Symbol.iterator]方法的对象都是可迭代的:
javascript复制const myIterable = {
*[Symbol.iterator]() {
yield 1;
yield 2;
yield 3;
}
};
for (const value of myIterable) {
console.log(value);
}
在响应式编程(如RxJava、Reactor)中,迭代器的概念被扩展为Publisher和Subscriber,支持更复杂的异步数据流处理。
让我们实现一个更贴近实际生产的迭代器:一个可以分页遍历数据库查询结果的迭代器。这个迭代器会:
java复制public class PagedDatabaseIterator<T> implements Iterator<T>, AutoCloseable {
private final DataSource dataSource;
private final String query;
private final Function<ResultSet, T> rowMapper;
private final int pageSize;
private Connection connection;
private PreparedStatement statement;
private ResultSet currentPage;
private int currentPositionInPage;
private boolean hasMoreRecords;
private final List<Predicate<T>> filters = new ArrayList<>();
public PagedDatabaseIterator(DataSource dataSource, String query,
Function<ResultSet, T> rowMapper, int pageSize) {
this.dataSource = dataSource;
this.query = query;
this.rowMapper = rowMapper;
this.pageSize = pageSize;
this.hasMoreRecords = true;
loadNextPage();
}
public void addFilter(Predicate<T> filter) {
filters.add(filter);
}
private void loadNextPage() {
closeCurrentPage();
try {
connection = dataSource.getConnection();
statement = connection.prepareStatement(
query + " LIMIT ? OFFSET ?",
ResultSet.TYPE_FORWARD_ONLY,
ResultSet.CONCUR_READ_ONLY
);
int offset = (getLoadedPagesCount() - 1) * pageSize;
statement.setInt(1, pageSize);
statement.setInt(2, offset);
currentPage = statement.executeQuery();
currentPositionInPage = 0;
advanceToNextValidRow();
} catch (SQLException e) {
close();
throw new RuntimeException("Failed to load next page", e);
}
}
private void advanceToNextValidRow() {
try {
while (true) {
if (!currentPage.next()) {
hasMoreRecords = false;
closeCurrentPage();
break;
}
T item = rowMapper.apply(currentPage);
if (passesFilters(item)) {
currentPositionInPage++;
return;
}
}
} catch (SQLException e) {
close();
throw new RuntimeException("Failed to advance to next row", e);
}
}
private boolean passesFilters(T item) {
for (Predicate<T> filter : filters) {
if (!filter.test(item)) {
return false;
}
}
return true;
}
private int getLoadedPagesCount() {
return (currentPositionInPage / pageSize) + 1;
}
@Override
public boolean hasNext() {
return hasMoreRecords;
}
@Override
public T next() {
if (!hasNext()) {
throw new NoSuchElementException();
}
try {
T item = rowMapper.apply(currentPage);
advanceToNextValidRow();
if (currentPositionInPage >= pageSize && hasMoreRecords) {
loadNextPage();
}
return item;
} catch (SQLException e) {
close();
throw new RuntimeException("Failed to read next item", e);
}
}
private void closeCurrentPage() {
try {
if (currentPage != null) {
currentPage.close();
}
if (statement != null) {
statement.close();
}
if (connection != null) {
connection.close();
}
} catch (SQLException e) {
// Log warning but don't throw
}
}
@Override
public void close() {
hasMoreRecords = false;
closeCurrentPage();
}
// 使用示例
public static void main(String[] args) {
DataSource dataSource = getDataSource(); // 获取数据源
String query = "SELECT id, name, email FROM users WHERE active = true";
try (PagedDatabaseIterator<User> iterator = new PagedDatabaseIterator<>(
dataSource, query,
rs -> new User(
rs.getLong("id"),
rs.getString("name"),
rs.getString("email")
),
100 // pageSize
)) {
iterator.addFilter(user -> user.getName().length() > 5);
while (iterator.hasNext()) {
User user = iterator.next();
processUser(user);
}
}
}
}
这个迭代器实现考虑了生产环境中的许多实际问题:
Spring框架在很多地方使用了迭代器模式。例如,在Resource接口中:
code复制Resource[] resources = ctx.getResources("classpath*:META-INF/spring.factories");
for (Resource resource : resources) {
// 处理每个资源文件
}
Hibernate提供了ScrollableResults接口,本质上是一个高级迭代器,可以高效地处理大量数据库记录:
code复制Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
ScrollableResults results = session.createQuery("FROM LargeEntity")
.setReadOnly(true)
.setCacheable(false)
.scroll(ScrollMode.FORWARD_ONLY);
while (results.next()) {
LargeEntity entity = (LargeEntity) results.get(0);
process(entity);
}
tx.commit();
session.close();
JUnit的参数化测试使用迭代器来提供测试数据:
code复制@RunWith(Parameterized.class)
public class FibonacciTest {
@Parameters
public static Collection<Object[]> data() {
return Arrays.asList(new Object[][] {
{0, 0}, {1, 1}, {2, 1}, {3, 2}, {4, 3}, {5, 5}
});
}
private int input;
private int expected;
public FibonacciTest(int input, int expected) {
this.input = input;
this.expected = expected;
}
@Test
public void test() {
assertEquals(expected, Fibonacci.compute(input));
}
}
对于原始类型集合,专门的迭代器可以避免装箱拆箱开销。例如,Java中有PrimitiveIterator.OfInt等专门接口。
对于小型不可变集合,可以缓存迭代器实例:
code复制private static final Iterator<Object> EMPTY_ITERATOR = new Iterator<Object>() {
@Override public boolean hasNext() { return false; }
@Override public Object next() { throw new NoSuchElementException(); }
};
public Iterator<Object> getIterator() {
return isEmpty() ? EMPTY_ITERATOR : new CustomIterator(this);
}
对于可能不会被使用的迭代器,可以延迟初始化资源:
code复制class LazyIterator<T> implements Iterator<T> {
private Supplier<Iterator<T>> supplier;
private Iterator<T> delegate;
public LazyIterator(Supplier<Iterator<T>> supplier) {
this.supplier = supplier;
}
@Override
public boolean hasNext() {
if (delegate == null) {
delegate = supplier.get();
}
return delegate.hasNext();
}
@Override
public T next() {
if (delegate == null) {
delegate = supplier.get();
}
return delegate.next();
}
}
对于远程数据或IO密集型操作,考虑批量获取数据:
code复制class BatchIterator<T> implements Iterator<T> {
private final int batchSize;
private final Function<Integer, List<T>> batchLoader;
private List<T> currentBatch;
private int currentIndex;
private int currentBatchNumber;
public BatchIterator(int batchSize, Function<Integer, List<T>> batchLoader) {
this.batchSize = batchSize;
this.batchLoader = batchLoader;
loadBatch(0);
}
private void loadBatch(int batchNumber) {
currentBatch = batchLoader.apply(batchNumber);
currentIndex = 0;
currentBatchNumber = batchNumber;
}
@Override
public boolean hasNext() {
if (currentIndex < currentBatch.size()) {
return true;
}
// 尝试加载下一批
List<T> nextBatch = batchLoader.apply(currentBatchNumber + 1);
if (!nextBatch.isEmpty()) {
currentBatch = nextBatch;
currentIndex = 0;
currentBatchNumber++;
return true;
}
return false;
}
@Override
public T next() {
if (!hasNext()) {
throw new NoSuchElementException();
}
return currentBatch.get(currentIndex++);
}
}
测试迭代器的基本功能:hasNext()和next()的正确行为:
code复制@Test
public void testEmptyIterator() {
Iterator<String> it = new EmptyIterator<>();
assertFalse(it.hasNext());
assertThrows(NoSuchElementException.class, it::next);
}
@Test
public void testSingleElementIterator() {
Iterator<String> it = new SingleElementIterator<>("test");
assertTrue(it.hasNext());
assertEquals("test", it.next());
assertFalse(it.hasNext());
assertThrows(NoSuchElementException.class, it::next);
}
@Test
public void testMultiElementIterator() {
Iterator<String> it = new ArrayIterator<>("a", "b", "c");
assertTrue(it.hasNext());
assertEquals("a", it.next());
assertTrue(it.hasNext());
assertEquals("b", it.next());
assertTrue(it.hasNext());
assertEquals("c", it.next());
assertFalse(it.hasNext());
assertThrows(NoSuchElementException.class, it::next);
}
如果迭代器声称支持并发修改或快速失败,需要测试相关行为:
code复制@Test
public void testConcurrentModification() {
List<String> list = new ArrayList<>(Arrays.asList("a", "b", "c"));
Iterator<String> it = list.iterator();
assertTrue(it.hasNext());
assertEquals("a", it.next());
list.add("d"); // 修改底层集合
// 根据实现决定期望行为
if (isFailFast()) {
assertThrows(ConcurrentModificationException.class, it::hasNext);
} else {
// 对于线程安全的迭代器,应该继续正常工作
assertTrue(it.hasNext());
assertEquals("b", it.next());
}
}
对于大型数据集迭代器,测试其内存使用和速度:
code复制@Test
public void testLargeDatasetPerformance() {
int size = 1_000_000;
Iterator<Integer> it = new RangeIterator(0, size);
long start = System.currentTimeMillis();
int count = 0;
while (it.hasNext()) {
it.next();
count++;
}
long duration = System.currentTimeMillis() - start;
assertEquals(size, count);
assertTrue(duration < 1000, "Iterated 1M items in " + duration + "ms");
// 检查内存使用
long memoryUsed = Runtime.getRuntime().totalMemory() -
Runtime.getRuntime().freeMemory();
assertTrue(memoryUsed < 10_000_000, "Used " + memoryUsed + " bytes");
}
对于需要管理资源的迭代器,确保资源被正确释放:
code复制@Test
public void testResourceCleanup() throws Exception {
TrackedResource resource = new TrackedResource();
try (ResourceIterator it = new ResourceIterator(resource)) {
while (it.hasNext()) {
it.next();
}
}
assertTrue(resource.isClosed());
}
private static class TrackedResource implements AutoCloseable {
private boolean closed;
public boolean isClosed() {
return closed;
}
@Override
public void close() {
closed = true;
}
}
错误示例:迭代器暴露了集合的内部结构
code复制class BadIterator implements Iterator<String> {
private List<String> internalList; // 暴露了内部列表引用
public BadIterator(List<String> list) {
this.internalList = list; // 危险!外部可能修改这个列表
// ...
}
// ...
}
正确做法:防御性复制或使用不可变视图
code复制class GoodIterator implements Iterator<String> {
private final List<String> snapshot;
public GoodIterator(List<String> list) {
this.snapshot = new ArrayList<>(list); // 创建防御性副本
// 或者
// this.snapshot = Collections.unmodifiableList(list);
}
// ...
}
错误示例:忘记关闭数据库资源
code复制class LeakyIterator implements Iterator<Result> {
private Connection conn;
private ResultSet rs;
public LeakyIterator(Connection conn, String query) {
this.conn = conn;
this.rs = conn.createStatement().executeQuery(query);
}
// ... 没有close方法 ...
}
正确做法:实现AutoCloseable并正确清理资源
code复制class SafeIterator implements Iterator<Result>, AutoCloseable {
private final Connection conn;
private final ResultSet rs;
private boolean closed;
public SafeIterator(Connection conn, String query) throws SQLException {
this.conn = conn;
this.rs = conn.createStatement().executeQuery(query);
}
@Override
public void close() throws SQLException {
if (!closed) {
closed = true;
rs.close();
conn.close();
}
}
// 添加finalizer作为最后防线(不推荐依赖,只是示例)
@Override
protected void finalize() throws Throwable {
try {
close();
} finally {
super.finalize();
}
}
// ...
}
错误示例:hasNext()有副作用或不可重复调用
code复制class ProblematicIterator implements Iterator<String> {
private boolean hasNextCalled;
private String nextItem;
@Override
public boolean hasNext() {
if (!hasNextCalled) {
nextItem = computeNext(); // 副作用:改变了状态
hasNextCalled = true;
}
return nextItem != null;
}
@Override
public String next() {
if (!hasNext()) throw new NoSuchElementException();
hasNextCalled = false;
return nextItem;
}
// ...
}
正确做法:hasNext()应该是幂等的(可重复调用不影响状态)
code复制class CorrectIterator implements Iterator<String> {
private String nextItem;
private boolean nextItemComputed;
@Override
public boolean hasNext() {
if (!nextItemComputed) {
nextItem = computeNext();
nextItemComputed = true;
}
return nextItem != null;
}
@Override
public String next() {
if (!hasNext()) throw new NoSuchElementException();
String result = nextItem;
nextItemComputed = false;
nextItem = null;
return result;
}
// ...
}
错误示例:没有处理并发修改的情况
code复制class NaiveListIterator<E> implements Iterator<E> {
private final List<E> list;
private int index;
public NaiveListIterator(List<E> list) {
this.list = list;
}
@Override
public boolean hasNext() {
return index < list.size(); // 如果list被并发修改,可能返回错误结果
}
@Override
public E next() {
return list.get(index++); // 可能抛出IndexOutOfBoundsException
}
}
正确做法:实现快速失败或线程安全策略
code复制// 快速失败版本
class FailFastListIterator<E> implements Iterator<E> {
private final List<E> list;
private int index;
private final int expectedModCount;
public FailFastListIterator(List<E> list) {
this.list = list;
this.expectedModCount = modCount(list);
}
private int modCount(List<E> list) {
// 通过反射获取modCount(实际中应该使用List的具体实现类)
try {
Field f = list.getClass().getDeclaredField("modCount");
f.setAccessible(true);
return (int) f.get(list);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
private void checkForComodification() {
if (modCount(list) != expectedModCount) {
throw new ConcurrentModificationException();
}
}
@Override
public boolean hasNext() {
checkForComodification();
return index < list.size();
}
@Override
public E next() {
checkForComodification();
if (index >= list.size()) throw new NoSuchElementException();
return list.get(index++);
}
}
// 线程安全版本(使用快照)
class ThreadSafeListIterator<E> implements Iterator<E> {
private final List<E> snapshot;
private int index;
public ThreadSafeListIterator(List<E> list) {
this.snapshot = new ArrayList<>(list); // 创建不可变快照
}
@Override
public boolean hasNext() {
return index < snapshot.size();
}
@Override
public E next() {
if (index >= snapshot.size()) throw new NoSuchElementException();
return snapshot.get(index++);
}
}
迭代器不一定非要有终点,可以实现无限序列:
code复制class FibonacciIterator implements Iterator<BigInteger> {
private BigInteger a = BigInteger.ZERO;
private BigInteger b = BigInteger.ONE;
@Override
public boolean hasNext() {
return true; // 总是有下一个
}
@Override
public BigInteger next() {
BigInteger result = a;
a = b;
b = result.add(b);
return result;
}
}
// 使用示例:打印前20个斐波那契数
Iterator<BigInteger> fib = new FibonacciIterator();
for (int i = 0; i < 20; i++) {
System.out.println(fib.next());
}
迭代器可以延迟计算,直到真正需要值的时候:
code复制class LazyMappingIterator<T, R> implements Iterator<R> {
private final Iterator<T> source;
private final Function<T, R> mapper;
public LazyMappingIterator(Iterator<T> source, Function<T, R> mapper) {
this.source = source;
this.mapper = mapper;
}
@Override
public boolean hasNext() {
return source.hasNext();
}
@Override
public R next() {
return mapper.apply(source.next()); // 只在next()时应用映射函数
}
}
// 使用示例
List<String> names = Arrays.asList("Alice", "Bob", "Charlie");
Iterator<Integer> lengths = new LazyMappingIterator<>(
names.iterator(),
String::length
);
可以将多个迭代器组合成一个:
code复制class CompositeIterator<T> implements Iterator<T> {
private final Iterator