Iterator<Iterator<T>>
を受け取り、それを に変換するネストされたイテレータを次に示しIterator<T>
ます。また、いくつかの高次のもの ( など) とともに sからIterator<V>
オブジェクトを成長させることを可能にする静的メソッドもあります。Map<K,V>
Iterator<Iterator<V>>
Map<K,Map<K,V>
Iterator<Iterator<Iterator<T>>>
スリーウェイ テストと MapMapMap テストでわかるように、より高いレベルのイテレータを反復処理するためのアイデアは、これらの 1 つを別の内部にラップすることです。
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
ください.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)));
}
}