这是一个嵌套迭代器,它将采用 anIterator<Iterator<T>>
并将其转换为Iterator<T>
. 还有一些静态方法可以让你Iterator<V>
从 s 中生成对象Map<K,V>
以及一些高阶的东西(Iterator<Iterator<V>>
等等Map<K,Map<K,V>
)。
如您在三路测试和 MapMapMap 测试中所见,在更高级别的迭代器上进行迭代的想法Iterator<Iterator<Iterator<T>>>
是将其中一个包装在另一个中。
public class NestedIterator<T> implements Iterator<T> {
// Outer iterator. Goes null when exhausted.
Iterator<Iterator<T>> i2 = null;
// Inner iterator. Goes null when exhausted.
Iterator<T> i1 = null;
// Next value.
T next = null;
// Takes a depth-2 iterator.
public NestedIterator(Iterator<Iterator<T>> i2) {
this.i2 = i2;
// Prime the pump.
if (i2 != null && i2.hasNext()) {
i1 = i2.next();
}
}
@Override
public boolean hasNext() {
// Is there one waiting?
if (next == null) {
// No!
// i1 will go null if it is exhausted.
if (i1 == null) {
// i1 is exhausted! Get a new one from i2.
if (i2 != null && i2.hasNext()) {
/// Get next.
i1 = i2.next();
// Set i2 null if exhausted.
if (!i2.hasNext()) {
// Exhausted.
i2 = null;
}
} else {
// Exhausted.
i2 = null;
}
}
// A null i1 now will mean all is over!
if (i1 != null) {
if (i1.hasNext()) {
// get next.
next = i1.next();
// Set i1 null if exhausted.
if (!i1.hasNext()) {
// Exhausted.
i1 = null;
}
} else {
// Exhausted.
i1 = null;
}
}
}
return next != null;
}
@Override
public T next() {
T n = next;
next = null;
return n;
}
@Override
public void remove() {
throw new UnsupportedOperationException("Not supported.");
}
// Iterating across Maps of Maps of Maps.
static <K1, K2, K3, V> Iterator<Iterator<Iterator<V>>> iiiV(Map<K1, Map<K2, Map<K3, V>>> i) {
final Iterator<Map<K2, Map<K3, V>>> iV = iV(i);
return new Iterator<Iterator<Iterator<V>>>() {
@Override
public boolean hasNext() {
return iV.hasNext();
}
@Override
public Iterator<Iterator<V>> next() {
return iiV(iV.next());
}
@Override
public void remove() {
iV.remove();
}
};
}
// Iterating across Maps of Maps.
static <K1, K2, V> Iterator<Iterator<V>> iiV(Map<K1, Map<K2, V>> i) {
final Iterator<Map<K2, V>> iV = iV(i);
return new Iterator<Iterator<V>>() {
@Override
public boolean hasNext() {
return iV.hasNext();
}
@Override
public Iterator<V> next() {
return iV(iV.next());
}
@Override
public void remove() {
iV.remove();
}
};
}
// Iterating across Map values.
static <K, V> Iterator<V> iV(final Map<K, V> map) {
return iV(map.entrySet().iterator());
}
// Iterating across Map.Entry Iterators.
static <K, V> Iterator<V> iV(final Iterator<Map.Entry<K, V>> i) {
return new Iterator<V>() {
@Override
public boolean hasNext() {
return i.hasNext();
}
@Override
public V next() {
return i.next().getValue();
}
@Override
public void remove() {
i.remove();
}
};
}
// **** TESTING ****
enum I {
I1, I2, I3;
};
public static void main(String[] args) {
// Two way test.
testTwoWay();
System.out.flush();
System.err.flush();
// Three way test.
testThreeWay();
System.out.flush();
System.err.flush();
// MapMap test
testMapMap();
System.out.flush();
System.err.flush();
// MapMapMap test
testMapMapMap();
System.out.flush();
System.err.flush();
}
private static void testMapMap() {
Map<String,String> m = new TreeMap<> ();
m.put("M-1", "V-1");
m.put("M-2", "V-2");
Map<String,Map<String,String>> mm = new TreeMap<> ();
mm.put("MM-1", m);
mm.put("MM-2", m);
System.out.println("MapMap");
Iterator<Iterator<String>> iiV = iiV(mm);
for (Iterator<String> i = new NestedIterator<>(iiV); i.hasNext();) {
System.out.print(i.next() + ",");
}
System.out.println();
}
private static void testMapMapMap() {
Map<String,String> m = new TreeMap<> ();
m.put("M-1", "V-1");
m.put("M-2", "V-2");
m.put("M-3", "V-3");
Map<String,Map<String,String>> mm = new TreeMap<> ();
mm.put("MM-1", m);
mm.put("MM-2", m);
Map<String,Map<String,Map<String,String>>> mmm = new TreeMap<> ();
mmm.put("MMM-1", mm);
mmm.put("MMM-2", mm);
System.out.println("MapMapMap");
Iterator<Iterator<Iterator<String>>> iiiV = iiiV(mmm);
for (Iterator<String> i = new NestedIterator<>(new NestedIterator<>(iiiV)); i.hasNext();) {
System.out.print(i.next() + ",");
}
System.out.println();
}
private static void testThreeWay() {
// Three way test.
System.out.println("Three way");
List<Iterator<I>> lii1 = Arrays.asList(
EnumSet.allOf(I.class).iterator(),
EnumSet.allOf(I.class).iterator(),
EnumSet.allOf(I.class).iterator(),
EnumSet.allOf(I.class).iterator());
List<Iterator<I>> lii2 = Arrays.asList(
EnumSet.allOf(I.class).iterator(),
EnumSet.allOf(I.class).iterator(),
EnumSet.allOf(I.class).iterator(),
EnumSet.allOf(I.class).iterator());
List<Iterator<I>> lii3 = Arrays.asList(
EnumSet.allOf(I.class).iterator(),
EnumSet.allOf(I.class).iterator(),
EnumSet.allOf(I.class).iterator(),
EnumSet.allOf(I.class).iterator());
Iterator<Iterator<Iterator<I>>> liii = Arrays.asList(
lii1.iterator(),
lii2.iterator(),
lii3.iterator()).iterator();
// Grow a 3-nest.
// Unroll it.
for (Iterator<I> ii = new NestedIterator<>(new NestedIterator<>(liii)); ii.hasNext();) {
I it = ii.next();
System.out.print(it + ",");
}
System.out.println();
}
private static void testTwoWay() {
System.out.println("Two way");
List<Iterator<I>> lii = Arrays.asList(
EnumSet.allOf(I.class).iterator(),
EnumSet.allOf(I.class).iterator(),
EnumSet.allOf(I.class).iterator());
for (Iterator<I> ii = new NestedIterator<>(lii.iterator()); ii.hasNext();) {
I it = ii.next();
System.out.print(it + ",");
}
System.out.println();
}
}
您的代码现在看起来像这样。请注意,我根本没有对此进行测试,并且我尽可能地使用了Map
代替,并且我正在使用Java 7 中的东西来帮助很多。ConcurrentSkipListMap
<>
public class MyCustomIndex implements Iterable<byte[]> {
private Map<byte[], Map<byte[], Map<byte[], byte[]>>> table;
public MyCustomIndex() {
this.table = new ConcurrentSkipListMap<>();
}
/**
* @param K
* @param F
* @param Q
*/
public void put(byte[] K, byte[] F, byte[] Q) {
Map<byte[], byte[]> QToDummyValueMap;
Map<byte[], Map<byte[], byte[]>> FToQMap;
if (table.containsKey(K)) {
FToQMap = table.get(K);
if (FToQMap.containsKey(F)) {
QToDummyValueMap = FToQMap.get(F);
} else {
QToDummyValueMap = new ConcurrentSkipListMap<>();
}
} else {
QToDummyValueMap = new ConcurrentSkipListMap<>();
FToQMap = new ConcurrentSkipListMap<>();
}
QToDummyValueMap.put(Q, new byte[0]);
FToQMap.put(F, QToDummyValueMap);
table.put(K, FToQMap);
}
public Map<byte[], Map<byte[], Map<byte[], byte[]>>> gettable() {
return table;
}
public Iterator<byte[]> iterator () {
// **** This is what I have been aiming at all along ****
return new NestedIterator(new NestedIterator<>(NestedIterator.iiiV(table)));
}
}