001/* Copyright (C) 2013 TU Dortmund 002 * This file is part of AutomataLib, http://www.automatalib.net/. 003 * 004 * AutomataLib is free software; you can redistribute it and/or 005 * modify it under the terms of the GNU Lesser General Public 006 * License version 3.0 as published by the Free Software Foundation. 007 * 008 * AutomataLib is distributed in the hope that it will be useful, 009 * but WITHOUT ANY WARRANTY; without even the implied warranty of 010 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 011 * Lesser General Public License for more details. 012 * 013 * You should have received a copy of the GNU Lesser General Public 014 * License along with AutomataLib; if not, see 015 * http://www.gnu.de/documents/lgpl.en.html. 016 */ 017package net.automatalib.commons.util.collections; 018 019import java.util.Iterator; 020import java.util.NoSuchElementException; 021 022public abstract class TwoLevelIterator<L1, L2, O> implements Iterator<O> { 023 024 private final Iterator<? extends L1> l1Iterator; 025 private L1 l1Object; 026 private Iterator<L2> l2Iterator; 027 028 public TwoLevelIterator(Iterator<? extends L1> l1Iterator) { 029 this.l1Iterator = l1Iterator; 030 this.l2Iterator = null; 031 } 032 033 protected abstract Iterator<L2> l2Iterator(L1 l1Object); 034 035 protected abstract O combine(L1 l1Object, L2 l2Object); 036 037 protected void nextL1() { 038 this.l2Iterator = null; 039 } 040 041 protected boolean advance() { 042 while(l2Iterator == null || !l2Iterator.hasNext()) { 043 if(!l1Iterator.hasNext()) 044 return false; 045 this.l1Object = l1Iterator.next(); 046 this.l2Iterator = l2Iterator(this.l1Object); 047 } 048 return true; 049 } 050 051 /* (non-Javadoc) 052 * @see java.util.Iterator#hasNext() 053 */ 054 @Override 055 public boolean hasNext() { 056 if(l2Iterator != null && l2Iterator.hasNext()) 057 return true; 058 return advance(); 059 } 060 061 /* (non-Javadoc) 062 * @see java.util.Iterator#next() 063 */ 064 @Override 065 public O next() { 066 if(l2Iterator == null || !l2Iterator.hasNext()) { 067 if(!advance()) 068 throw new NoSuchElementException(); 069 } 070 return combine(l1Object, l2Iterator.next()); 071 } 072 073 /* (non-Javadoc) 074 * @see java.util.Iterator#remove() 075 */ 076 @Override 077 public void remove() { 078 l2Iterator.remove(); 079 } 080 081 082 083}