Java 迭代器模式 3 大实战场景:从 JDBC ResultSet 到自定义集合遍历
Java 迭代器模式 3 大实战场景:从 JDBC ResultSet 到自定义集合遍历
在 Java 开发中,我们经常需要处理各种集合数据的遍历操作。迭代器模式(Iterator Pattern)作为一种行为型设计模式,提供了一种统一的方式来访问集合对象中的元素,而无需暴露其内部表示。本文将深入探讨迭代器模式在 Java 生态中的三个高级应用场景,帮助开发者更好地理解这一模式的实际价值。
1. JDBC ResultSet 的迭代器模式实现
JDBC(Java Database Connectivity)是 Java 连接数据库的标准 API,而 ResultSet 则是查询结果集的载体。ResultSet 本质上就是一个迭代器模式的经典实现。
1.1 ResultSet 的迭代器特性
ResultSet 提供了类似迭代器的接口来遍历查询结果:
try (Connection conn = DriverManager.getConnection(url, user, password);
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery("SELECT * FROM users")) {
while (rs.next()) { // 相当于 hasNext()
int id = rs.getInt("id"); // 相当于 next()
String name = rs.getString("name");
// 处理数据...
}
}
关键点分析 :
next()方法:将游标移动到下一行,并返回是否有更多数据- 各种
getXxx()方法:获取当前行的列数据 - 内部状态管理:ResultSet 维护了当前行的位置信息
1.2 自定义 ResultSet 包装器
我们可以进一步封装 ResultSet,使其更符合迭代器模式的标准接口:
public class ResultSetIterator<T> implements Iterator<T> {
private final ResultSet rs;
private final Function<ResultSet, T> mapper;
private boolean hasNext;
public ResultSetIterator(ResultSet rs, Function<ResultSet, T> mapper) {
this.rs = rs;
this.mapper = mapper;
try {
this.hasNext = rs.next();
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
@Override
public boolean hasNext() {
return hasNext;
}
@Override
public T next() {
if (!hasNext) throw new NoSuchElementException();
try {
T value = mapper.apply(rs);
hasNext = rs.next();
return value;
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
}
使用示例:
ResultSetIterator<User> iterator = new ResultSetIterator<>(rs, rs ->
new User(rs.getInt("id"), rs.getString("name")));
while (iterator.hasNext()) {
User user = iterator.next();
System.out.println(user);
}
2. Java 8 Stream API 与 Spliterator
Java 8 引入的 Stream API 为集合操作提供了函数式编程能力,而其底层依赖于 Spliterator(可分割迭代器)这一增强版迭代器。
2.1 Spliterator 核心方法
Spliterator 接口定义了以下关键方法:
| 方法 | 描述 |
|---|---|
boolean tryAdvance(Consumer<? super T> action) |
尝试处理下一个元素 |
Spliterator<T> trySplit() |
尝试分割迭代器以支持并行处理 |
long estimateSize() |
估算剩余元素数量 |
int characteristics() |
返回迭代器特性标志 |
2.2 自定义集合的 Spliterator 实现
假设我们有一个自定义的二叉树结构,可以为其实现 Spliterator:
public class BinaryTree<T> {
private Node<T> root;
private static class Node<T> {
T value;
Node<T> left, right;
}
public Spliterator<T> spliterator() {
return new BinaryTreeSpliterator<>(root);
}
private static class BinaryTreeSpliterator<T> implements Spliterator<T> {
private final Deque<Node<T>> stack = new ArrayDeque<>();
public BinaryTreeSpliterator(Node<T> root) {
if (root != null) stack.push(root);
}
@Override
public boolean tryAdvance(Consumer<? super T> action) {
if (stack.isEmpty()) return false;
Node<T> current = stack.pop();
action.accept(current.value);
if (current.right != null) stack.push(current.right);
if (current.left != null) stack.push(current.left);
return true;
}
@Override
public Spliterator<T> trySplit() {
// 简化实现,实际中可以实现更复杂的分割逻辑
return null;
}
@Override
public long estimateSize() {
return Long.MAX_VALUE; // 未知大小
}
@Override
public int characteristics() {
return Spliterator.ORDERED | Spliterator.NONNULL;
}
}
}
使用示例:
BinaryTree<String> tree = new BinaryTree<>();
// 填充树结构...
tree.spliterator().forEachRemaining(System.out::println);
3. 自定义数据结构的迭代器实现
对于复杂的数据结构(如图、树等),标准集合接口可能无法满足需求,这时需要自定义迭代器。
3.1 二叉树的前序和中序迭代器
下面展示如何为二叉树实现两种不同的遍历方式:
public class BinaryTree<T> implements Iterable<T> {
private Node<T> root;
public Iterator<T> preOrderIterator() {
return new PreOrderIterator();
}
public Iterator<T> inOrderIterator() {
return new InOrderIterator();
}
// 前序遍历迭代器
private class PreOrderIterator implements Iterator<T> {
private final Deque<Node<T>> stack = new ArrayDeque<>();
public PreOrderIterator() {
if (root != null) stack.push(root);
}
@Override
public boolean hasNext() {
return !stack.isEmpty();
}
@Override
public T next() {
Node<T> current = stack.pop();
if (current.right != null) stack.push(current.right);
if (current.left != null) stack.push(current.left);
return current.value;
}
}
// 中序遍历迭代器
private class InOrderIterator implements Iterator<T> {
private final Deque<Node<T>> stack = new ArrayDeque<>();
private Node<T> current;
public InOrderIterator() {
current = root;
pushLeft(current);
}
private void pushLeft(Node<T> node) {
while (node != null) {
stack.push(node);
node = node.left;
}
}
@Override
public boolean hasNext() {
return !stack.isEmpty();
}
@Override
public T next() {
Node<T> node = stack.pop();
pushLeft(node.right);
return node.value;
}
}
}
3.2 图结构的迭代器实现
对于图结构,我们可以实现广度优先搜索(BFS)和深度优先搜索(DFS)迭代器:
public class Graph<T> implements Iterable<T> {
private final Map<T, List<T>> adjacencyList = new HashMap<>();
public void addEdge(T source, T destination) {
adjacencyList.computeIfAbsent(source, k -> new ArrayList<>()).add(destination);
}
public Iterator<T> bfsIterator(T start) {
return new BfsIterator(start);
}
public Iterator<T> dfsIterator(T start) {
return new DfsIterator(start);
}
private class BfsIterator implements Iterator<T> {
private final Queue<T> queue = new LinkedList<>();
private final Set<T> visited = new HashSet<>();
public BfsIterator(T start) {
queue.add(start);
visited.add(start);
}
@Override
public boolean hasNext() {
return !queue.isEmpty();
}
@Override
public T next() {
T current = queue.remove();
for (T neighbor : adjacencyList.getOrDefault(current, Collections.emptyList())) {
if (!visited.contains(neighbor)) {
visited.add(neighbor);
queue.add(neighbor);
}
}
return current;
}
}
private class DfsIterator implements Iterator<T> {
private final Deque<T> stack = new ArrayDeque<>();
private final Set<T> visited = new HashSet<>();
public DfsIterator(T start) {
stack.push(start);
visited.add(start);
}
@Override
public boolean hasNext() {
return !stack.isEmpty();
}
@Override
public T next() {
T current = stack.pop();
for (T neighbor : adjacencyList.getOrDefault(current, Collections.emptyList())) {
if (!visited.contains(neighbor)) {
visited.add(neighbor);
stack.push(neighbor);
}
}
return current;
}
}
}
4. 迭代器模式的高级应用技巧
4.1 过滤迭代器
我们可以创建装饰器模式的过滤迭代器,只返回满足特定条件的元素:
public class FilteringIterator<T> implements Iterator<T> {
private final Iterator<T> source;
private final Predicate<T> predicate;
private T nextElement;
private boolean hasNext;
public FilteringIterator(Iterator<T> source, Predicate<T> predicate) {
this.source = source;
this.predicate = predicate;
advance();
}
private void advance() {
hasNext = false;
while (source.hasNext()) {
nextElement = source.next();
if (predicate.test(nextElement)) {
hasNext = true;
break;
}
}
}
@Override
public boolean hasNext() {
return hasNext;
}
@Override
public T next() {
if (!hasNext) throw new NoSuchElementException();
T result = nextElement;
advance();
return result;
}
}
使用示例:
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
Iterator<Integer> evenNumbers = new FilteringIterator<>(
numbers.iterator(),
n -> n % 2 == 0
);
while (evenNumbers.hasNext()) {
System.out.println(evenNumbers.next());
}
4.2 线程安全迭代器
在多线程环境中,我们需要确保迭代器的线程安全性:
public class SynchronizedIterator<T> implements Iterator<T> {
private final Iterator<T> source;
private final Object lock;
public SynchronizedIterator(Iterator<T> source, Object lock) {
this.source = source;
this.lock = lock != null ? lock : this;
}
@Override
public boolean hasNext() {
synchronized (lock) {
return source.hasNext();
}
}
@Override
public T next() {
synchronized (lock) {
return source.next();
}
}
@Override
public void remove() {
synchronized (lock) {
source.remove();
}
}
}
4.3 组合迭代器
对于嵌套集合结构,我们可以创建组合迭代器来扁平化遍历:
public class CompositeIterator<T> implements Iterator<T> {
private final Iterator<? extends Iterable<T>> outerIterator;
private Iterator<T> currentInnerIterator;
public CompositeIterator(Iterable<? extends Iterable<T>> outerIterable) {
this.outerIterator = outerIterable.iterator();
this.currentInnerIterator = Collections.emptyIterator();
}
@Override
public boolean hasNext() {
while (!currentInnerIterator.hasNext()) {
if (!outerIterator.hasNext()) return false;
currentInnerIterator = outerIterator.next().iterator();
}
return true;
}
@Override
public T next() {
if (!hasNext()) throw new NoSuchElementException();
return currentInnerIterator.next();
}
}
使用示例:
List<List<String>> nestedList = Arrays.asList(
Arrays.asList("A", "B", "C"),
Arrays.asList("D", "E"),
Collections.emptyList(),
Arrays.asList("F", "G", "H")
);
Iterator<String> compositeIt = new CompositeIterator<>(nestedList);
while (compositeIt.hasNext()) {
System.out.println(compositeIt.next());
}
在实际项目中,迭代器模式的应用远比这些基础示例复杂。理解其核心思想并灵活运用,可以显著提升代码的可维护性和扩展性。
更多推荐




所有评论(0)