Java中可通过封装Iterator实现过滤游标类,它不修改原集合,而是延迟查找下一个匹配元素并缓存,在hasNext()和next()中按需跳过不满足条件的元素,保持懒加载特性。

Java 中可以通过封装 Iterator 并在 hasNext() 和 next() 方法中加入过滤逻辑,实现一个自定义的“过滤游标类”。它不是真正修改原集合,而是按需跳过不满足条件的元素,对外表现为一个只遍历符合条件元素的迭代器。
核心思路:包装原始 Iterator,延迟判断
不提前遍历全部元素生成新集合(避免内存浪费和重复计算),而是在每次调用 next() 时,向后查找**下一个匹配的元素**,并缓存它。这样既保持了迭代器的懒加载特性,又实现了过滤语义。
- 内部持有一个被包装的
Iterator<t></t> - 维护一个临时字段(如
nextMatch)缓存下一个待返回的匹配元素 -
hasNext()触发查找逻辑,确保nextMatch != null或已耗尽 -
next()返回缓存值,并立即清空缓存、触发下一次查找
基础实现:FilteringIterator
以下是一个泛型、线程不安全但简洁可用的实现:
public class FilteringIterator<T> implements Iterator<T> {
private final Iterator<T> source;
private final Predicate<T> predicate;
private T nextMatch;
<pre class="brush:php;toolbar:false;">public FilteringIterator(Iterator<T> source, Predicate<T> predicate) {
this.source = Objects.requireNonNull(source);
this.predicate = Objects.requireNonNull(predicate);
findNextMatch(); // 初始化找第一个匹配项
}
@Override
public boolean hasNext() {
return nextMatch != null;
}
@Override
public T next() {
if (nextMatch == null) {
throw new NoSuchElementException();
}
T result = nextMatch;
nextMatch = null;
findNextMatch();
return result;
}
private void findNextMatch() {
while (source.hasNext()) {
T item = source.next();
if (predicate.test(item)) {
nextMatch = item;
return;
}
}
// 没找到,nextMatch 保持为 null
}
}
立即学习“Java免费学习笔记(深入)”;
使用示例:过滤字符串长度大于 3 的元素
假设你有一个 List<string></string>,想只遍历长度 > 3 的字符串:
List<String> list = Arrays.asList("a", "hello", "hi", "world", "");
Iterator<String> filtered = new FilteringIterator<>(
list.iterator(),
s -> s.length() > 3
);
<p>while (filtered.hasNext()) {
System.out.println(filtered.next()); // 输出: "hello", "world"
}
注意:该迭代器是一次性使用的,不可重复调用 hasNext() 多次而不调用 next() —— 因为查找逻辑在 findNextMatch() 中是推进式的,多次 hasNext() 不会重复检查同一元素,但也不会回退。
进阶建议:转为静态工厂方法 + 支持 remove()
实际项目中可进一步优化:
- 提供静态工厂方法(如
FilteringIterator.of(iter, pred)),提升可读性 - 重写
remove()方法(委托给源迭代器),前提是源迭代器支持移除操作 - 若需多线程安全,需加同步或改用线程安全的源迭代器(但通常迭代器本身不设计为共享)
- JDK 9+ 可考虑用
StreamSupport.stream(spliterator, false).filter(...).iterator()替代,但底层仍是类似思路


















