实现多层嵌套迭代器遍历:现有嵌套if结构是否有更优替代方案?
多层嵌套迭代器的优化实现
问题背景
需要实现一个Iterator<E>,内部需遍历多层私有迭代器(如Iterator<A>、Iterator<B>、Iterator<C>),核心规则如下:
Iterator<A>在自定义迭代器生命周期内始终存在Iterator<B>由当前A实例生成,Iterator<C>由当前B实例生成- 每次迭代时,若
Iterator<C>耗尽,需推进Iterator<B>生成新的Iterator<C>;若Iterator<B>耗尽,则推进Iterator<A>生成新的Iterator<B> - 实际场景涉及5-6层嵌套,当前嵌套if结构冗余丑陋,需更优实现方案
现有实现代码:
if ( this.cIterator == null || ! this.cIterator.hasNext() ) { // 没有C迭代器或当前C迭代器已耗尽,需要从下一个B生成新的C迭代器 if ( this.bIterator == null || !this.bIterator.hasNext() ) { // 没有B迭代器或当前B迭代器已耗尽,需要从下一个A生成新的B迭代器 if ( this.aIterator == null || !this.aIterator.hasNext() ) { // A迭代器不存在或已耗尽,迭代结束 throw new NoSuchElementException(); } // 获取下一个A,生成对应的B迭代器 this.currentA = this.aIterator.next(); this.bIterator = this.currentA.getIteratorSourceCollection().iterator(); // 注:实际场景中bIterator一定有元素 } // 获取下一个B,生成对应的C迭代器 this.currentB = bIterator.next(); this.cIterator = this.currentB.getIteratorSourceCollection().iterator(); // 注:实际场景中cIterator一定有元素 } // 返回封装后的E实例 return new E(this.currentA, this.currentB, this.cIterator.next());
优化方案1:拆分层级逻辑为独立方法
将每一层迭代器的初始化/推进逻辑拆分为独立方法,消除嵌套结构,让代码职责更单一,扩展性更强:
@Override public E next() { ensureCIteratorHasNext(); return new E(currentA, currentB, cIterator.next()); } private void ensureCIteratorHasNext() { if (cIterator == null || !cIterator.hasNext()) { ensureBIteratorHasNext(); currentB = bIterator.next(); cIterator = currentB.getIteratorSourceCollection().iterator(); } } private void ensureBIteratorHasNext() { if (bIterator == null || !bIterator.hasNext()) { ensureAIteratorHasNext(); currentA = aIterator.next(); bIterator = currentA.getIteratorSourceCollection().iterator(); } } private void ensureAIteratorHasNext() { if (aIterator == null || !aIterator.hasNext()) { throw new NoSuchElementException(); } }
扩展到5-6层时,仅需新增对应的ensureXXXIteratorHasNext()方法即可,代码结构始终保持整洁。
优化方案2:迭代器链(适配动态层级场景)
如果层级数量可能变化,可通过栈维护迭代器链,动态处理层级推进逻辑:
private Deque<Iterator<?>> iteratorStack = new ArrayDeque<>(); private A currentA; private B currentB; public CustomIterator(Iterator<A> aIterator) { this.iteratorStack.push(aIterator); } @Override public boolean hasNext() { // 实现hasNext逻辑:确保栈顶迭代器有可遍历元素,或能推进到下一层有元素的迭代器 Iterator<?> temp = iteratorStack.peek(); while (temp != null && !temp.hasNext()) { iteratorStack.pop(); temp = iteratorStack.peek(); } return temp != null && temp.hasNext(); } @Override public E next() { while (!iteratorStack.isEmpty()) { Iterator<?> top = iteratorStack.peek(); if (top.hasNext()) { Object next = top.next(); if (next instanceof A) { currentA = (A) next; iteratorStack.push(currentA.getIteratorSourceCollection().iterator()); } else if (next instanceof B) { currentB = (B) next; iteratorStack.push(currentB.getIteratorSourceCollection().iterator()); } else if (next instanceof C) { return new E(currentA, currentB, (C) next); } } else { iteratorStack.pop(); if (iteratorStack.isEmpty()) { throw new NoSuchElementException(); } } } throw new NoSuchElementException(); }
新增层级时仅需在next()方法中补充对应类型的处理逻辑,无需大幅修改现有代码。
优化方案3:Java Stream扁平化(极简实现)
若场景允许使用Stream API,可通过多层flatMap扁平化嵌套结构,直接生成目标迭代器:
private Iterator<E> delegateIterator; public CustomIterator(Iterator<A> aIterator) { this.delegateIterator = StreamSupport.stream( Spliterators.spliteratorUnknownSize(aIterator, Spliterator.ORDERED), false) .flatMap(a -> a.getIteratorSourceCollection().stream() .flatMap(b -> b.getIteratorSourceCollection().stream() .map(c -> new E(a, b, c)))) .iterator(); } @Override public boolean hasNext() { return delegateIterator.hasNext(); } @Override public E next() { return delegateIterator.next(); }
此方案无需手动维护迭代器状态,代码量极少,可读性极强。需注意:若底层集合在迭代过程中被修改,Stream的行为可能与原始迭代器不一致,需根据实际场景评估适用性。
内容的提问来源于stack exchange,提问作者Matthew McPeak
相关产品推荐
相关产品推荐

