2013-03-25 3 views
0

나는 3 차원 ConcurrentSkipListMap을 작성했지만 그 위에 반복하는 방법을 찾을 수는 없습니다. 어떻게 내가 같은 iterator을 정의합니까.3 차원 ConcurrentSkipListMap map

import java.util.concurrent.ConcurrentSkipListMap; 
/** 
* Helper implementation to handle 3 dimensional sorted maps 
*/ 
public class MyCustomIndex { 
    private ConcurrentSkipListMap<byte[], ConcurrentSkipListMap<byte[], ConcurrentSkipListMap<byte[], byte[]>>> table; 

    public MyCustomIndex() { 
     this.table = new ConcurrentSkipListMap<byte[], ConcurrentSkipListMap<byte[], ConcurrentSkipListMap<byte[], byte[]>>>(new CustomComparator); 
    } 
    /** 
    * 
    * @param K 
    * @param F 
    * @param Q 
    */ 
    public void put(byte[] K, byte[] F, byte[] Q) { 
     ConcurrentSkipListMap<byte[], byte[]> QToDummyValueMap; 
     ConcurrentSkipListMap<byte[], ConcurrentSkipListMap<byte[], byte[]>> FToQMap; 

     if(table.containsK(K)) { 
      FToQMap = table.get(K); 
      if (FToQMap.containsK(F)) { 
       QToDummyValueMap = FToQMap.get(F); 
      } else { 
       QToDummyValueMap = new ConcurrentSkipListMap<byte[], byte[]>(new CustomComparator); 
      } 
     } else { 
      QToDummyValueMap = new ConcurrentSkipListMap<byte[], byte[]>(new CustomComparator); 
      FToQMap = new ConcurrentSkipListMap<byte[], ConcurrentSkipListMap<byte[], byte[]>>(new CustomComparator); 
     }  
     QToDummyValueMap.put(Q, new byte[0]); 
     FToQMap.put(F, QToDummyValueMap); 
     table.put(K, FToQMap); 
    } 

    public ConcurrentSkipListMap<byte[], ConcurrentSkipListMap<byte[], ConcurrentSkipListMap<byte[], byte[]>>> gettable() { 
     return table; 
    } 
    public void settable(
      ConcurrentSkipListMap<byte[], ConcurrentSkipListMap<byte[], ConcurrentSkipListMap<byte[], byte[]>>> table) { 
     this.table = table; 
    } 

} 

답변

0

은 여기 Iterator<Iterator<T>>을하고 Iterator<T>로 바뀝니다 중첩 된 반복자입니다. 또한 Iterator<V> 개체를 Map<K,V> 밖으로 성장시킬 수있는 정적 메서드가 있으며 일부 고차원 도구 (Iterator<Iterator<V>>Map<K,Map<K,V> 등)가 함께 제공됩니다.

Iterator<Iterator<Iterator<T>>>과 같이 더 높은 수준의 반복기를 반복하는 아이디어는 3 방향 테스트 및 MapMapMap 테스트에서 볼 수있는 것처럼 다른 쪽을 다른 안에 래핑하는 것입니다.

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(); 
    } 
} 

코드는 이제 이와 비슷한 형태가 될 수 있습니다. 필자는 이것을 전혀 테스트하지 않았으므로 가능한 경우 ConcurrentSkipListMap 대신 Map을 사용하고 Java 7에서 <>을 많이 사용하고 있습니다.

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))); 
    } 

}