目录
从智能图书馆看元素遍历
📚 真实场景设定:
某元宇宙图书馆的藏书系统包含:
- 全息投影书架(环形数组实现)
- 量子纠缠书库(双向链表结构)
- 时空档案室(多维度树状存储)
- 记忆碎片仓库(图结构网络)
如何让读者用统一的方式查阅所有这些异形存储?答案就是打造一把智能"图书遥控器"——迭代器模式现在启动!
一、基础篇:打造万能书库遥控器
1.1 迭代器架构蓝图
1.2 基础迭代器实现
// 迭代器接口
interface BookIterator<T> {
boolean hasNext();
T next();
default void remove() {
throw new UnsupportedOperationException();
}
}
// 数组书架的迭代器
class ArrayBookIterator implements BookIterator<Book> {
private Book[] books;
private int position;
public ArrayBookIterator(Book[] books) {
this.books = books;
}
public boolean hasNext() {
return position < books.length && books[position] != null;
}
public Book next() {
return books[position++];
}
}
// 链表书架的迭代器
class LinkedListBookIterator implements BookIterator<Book> {
private Node current;
public LinkedListBookIterator(Node head) {
this.current = head;
}
public boolean hasNext() {
return current != null;
}
public Book next() {
Book book = current.data;
current = current.next;
return book;
}
}
// 图书馆客户端
public class LibraryClient {
public static void main(String[] args) {
// 创建不同类型的书架
BookShelf arrayShelf = new ArrayBookShelf();
BookShelf linkedShelf = new LinkedListBookShelf();
// 统一遍历方式
searchBook(arrayShelf.createIterator(), "三体");
searchBook(linkedShelf.createIterator(), "时间简史");
}
private static void searchBook(BookIterator<Book> it, String title) {
while(it.hasNext()) {
Book book = it.next();
if(book.getTitle().equals(title)) {
System.out.println("📖 找到书籍:" + book);
return;
}
}
System.out.println("❌ 未找到相关书籍");
}
}
二、进阶篇:解锁高阶遥控功能
2.1 双向迭代器(时光倒流)
interface ReversibleIterator<T> extends BookIterator<T> {
boolean hasPrevious();
T previous();
void add(T item);
}
// 支持双向操作的数组迭代器
class ReversibleArrayIterator implements ReversibleIterator<Book> {
private Book[] books;
private int cursor = -1;
public ReversibleArrayIterator(Book[] books) {
this.books = books;
}
public boolean hasNext() {
return cursor < books.length - 1;
}
public Book next() {
return books[++cursor];
}
public boolean hasPrevious() {
return cursor > 0;
}
public Book previous() {
return books[--cursor];
}
public void add(Book book) {
// 动态扩容实现略
System.arraycopy(books, cursor, books, cursor+1, books.length-cursor-1);
books[cursor] = book;
}
}
// 时空穿越搜索
ReversibleIterator<Book> timeMachine = new ReversibleArrayIterator(books);
while(timeMachine.hasNext()) {
Book book = timeMachine.next();
if(book.getYear() > 2050) {
System.out.println("发现未来书籍:" + book);
timeMachine.previous(); // 回到上一个
timeMachine.add(new Book("时空回溯指南")); // 插入新书
}
}
2.2 智能过滤迭代器
// 过滤迭代器基类
abstract class FilterIterator<T> implements BookIterator<T> {
protected BookIterator<T> iterator;
public FilterIterator(BookIterator<T> iterator) {
this.iterator = iterator;
}
public boolean hasNext() {
while(iterator.hasNext()) {
if(matchCondition(iterator.next())) {
return true;
}
}
return false;
}
public T next() {
return iterator.next();
}
protected abstract boolean matchCondition(T item);
}
// 类型过滤迭代器
class GenreFilterIterator extends FilterIterator<Book> {
private String genre;
public GenreFilterIterator(BookIterator<Book> iterator, String genre) {
super(iterator);
this.genre = genre;
}
protected boolean matchCondition(Book book) {
return book.getGenre().equalsIgnoreCase(genre);
}
}
// 使用示例
BookIterator<Book> sciFiBooks = new GenreFilterIterator(
new ArrayBookIterator(books), "科幻"
);
while(sciFiBooks.hasNext()) {
System.out.println("科幻书籍:" + sciFiBooks.next());
}
三、性能对决:不同迭代方式对比
3.1 遍历效率测试
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.MICROSECONDS)
public class IteratorBenchmark {
@State(Scope.Thread)
public static class Data {
public ArrayList<Book> arrayList = new ArrayList<>();
public LinkedList<Book> linkedList = new LinkedList<>();
@Setup
public void init() {
// 初始化10万本书籍数据
IntStream.range(0, 100000).forEach(i -> {
Book book = new Book("Book" + i);
arrayList.add(book);
linkedList.add(book);
});
}
}
@Benchmark
public void testForLoopArrayList(Data data) {
for(int i=0; i<data.arrayList.size(); i++) {
data.arrayList.get(i).hashCode();
}
}
@Benchmark
public void testIteratorArrayList(Data data) {
Iterator<Book> it = data.arrayList.iterator();
while(it.hasNext()) {
it.next().hashCode();
}
}
@Benchmark
public void testForEachArrayList(Data data) {
data.arrayList.forEach(Book::hashCode);
}
}
// 测试结果 (ns/op):
// Benchmark Mode Cnt Score Error
// testForLoopArrayList thrpt 5 435.67 ± 6.45
// testIteratorArrayList thrpt 5 628.34 ± 12.56
// testForEachArrayList thrpt 5 572.89 ± 9.87
3.2 内存开销对比
class MemoryTest {
public static void main(String[] args) {
List<Book> list = new ArrayList<>(1000000);
Iterator<Book> it = list.iterator();
System.out.println("ArrayList迭代器内存:" +
GraphLayout.parseInstance(it).totalSize());
List<Book> linked = new LinkedList<>(list);
Iterator<Book> linkedIt = linked.iterator();
System.out.println("LinkedList迭代器内存:" +
GraphLayout.parseInstance(linkedIt).totalSize());
}
}
// 测试结果:
// ArrayList迭代器内存:24 bytes
// LinkedList迭代器内存:40 bytes
四、实战应用:现代框架中的迭代器
4.1 Spring Data分页迭代
// 分页处理大型数据集
public class BigDataProcessor {
@Autowired
private BookRepository repository;
public void processAllBooks() {
Pageable pageable = PageRequest.of(0, 100);
Page<Book> page;
do {
page = repository.findAll(pageable);
page.getContent().forEach(this::processBook);
pageable = page.nextPageable();
} while(page.hasNext());
}
private void processBook(Book book) {
// 处理逻辑
}
}
4.2 Java Stream并行迭代
// 并行处理图书馆数据
public void parallelProcessBooks() {
Spliterator<Book> spliterator = bookShelf.spliterator();
StreamSupport.stream(spliterator, true) // 启用并行
.filter(b -> b.getYear() > 2020)
.map(Book::analyzeContent)
.forEach(System.out::println);
}
// 自定义Spliterator
class BookShelfSpliterator implements Spliterator<Book> {
private final Book[] array;
private int index;
public BookShelfSpliterator(Book[] array) {
this.array = array;
}
public boolean tryAdvance(Consumer<? super Book> action) {
if(index < array.length) {
action.accept(array[index++]);
return true;
}
return false;
}
public Spliterator<Book> trySplit() {
// 实现分割逻辑用于并行
}
}
五、防翻车指南:迭代器模式十诫
- 避免并发修改 → 使用快速失败迭代器
- 注意资源泄漏 → 关闭AutoCloseable迭代器
- 禁用重复迭代 → 单次遍历迭代器明确标注
- 空迭代处理 → 返回EmptyIterator实例
- 性能敏感区慎用 → 直接访问数据结构
- 不可变保证 → 返回不可修改迭代器
- 类型安全 → 使用泛型迭代器接口
- 组合迭代危险 → 避免迭代器嵌套修改
- 懒加载优化 → 延迟初始化迭代状态
- 错误处理机制 → 定义明确异常类型
终极挑战:设计跨宇宙迭代器
架构设计题:
当需要支持:
- 多维度空间遍历
- 量子叠加态观测
- 平行宇宙切换
- 时间轴回溯
如何设计:
- 多元宇宙坐标系统
- 量子观测锁定机制
- 平行分支记录器
- 时空连续性保障