001package net.automatalib.commons.util.collections; 002 003import java.util.Iterator; 004 005 006public abstract class ThreeLevelIterator<L1, L2, L3, O> implements Iterator<O> { 007 008 private static class Outer<L1,L2> { 009 private L1 l1Item; 010 private L2 l2Item; 011 } 012 013 private class OuterIterator extends TwoLevelIterator<L1,L2,Outer<L1,L2>> { 014 015 private final Outer<L1,L2> value = new Outer<>(); 016 017 public OuterIterator(Iterator<L1> l1Iterator) { 018 super(l1Iterator); 019 } 020 021 @Override 022 protected Iterator<L2> l2Iterator(L1 l1Object) { 023 return ThreeLevelIterator.this.l2Iterator(l1Object); 024 } 025 026 @Override 027 protected Outer<L1, L2> combine(L1 l1Object, L2 l2Object) { 028 value.l1Item = l1Object; 029 value.l2Item = l2Object; 030 return value; 031 } 032 } 033 034 private class InnerIterator extends TwoLevelIterator<Outer<L1,L2>,L3,O> { 035 public InnerIterator(Iterator<Outer<L1, L2>> outerIterator) { 036 super(outerIterator); 037 } 038 @Override 039 protected Iterator<L3> l2Iterator(Outer<L1, L2> outer) { 040 return ThreeLevelIterator.this.l3Iterator(outer.l1Item, outer.l2Item); 041 } 042 @Override 043 protected O combine(Outer<L1, L2> outer, L3 l3Object) { 044 return ThreeLevelIterator.this.combine(outer.l1Item, outer.l2Item, l3Object); 045 } 046 } 047 048 private final InnerIterator innerIterator; 049 050 public ThreeLevelIterator(Iterator<L1> l1Iterator) { 051 OuterIterator outerIterator = new OuterIterator(l1Iterator); 052 this.innerIterator = new InnerIterator(outerIterator); 053 } 054 055 056 protected abstract Iterator<L2> l2Iterator(L1 l1Object); 057 protected abstract Iterator<L3> l3Iterator(L1 l1Object, L2 l2Object); 058 059 060 protected abstract O combine(L1 l1Object, L2 l2Object, L3 l3Object); 061 062 063 /* (non-Javadoc) 064 * @see java.util.Iterator#hasNext() 065 */ 066 @Override 067 public boolean hasNext() { 068 return innerIterator.hasNext(); 069 } 070 071 072 /* (non-Javadoc) 073 * @see java.util.Iterator#next() 074 */ 075 @Override 076 public O next() { 077 return innerIterator.next(); 078 } 079 080 081 /* (non-Javadoc) 082 * @see java.util.Iterator#remove() 083 */ 084 @Override 085 public void remove() { 086 innerIterator.remove(); 087 } 088 089 090 091}