Home | History | Annotate | Download | only in collect
      1 /*
      2  * Copyright (C) 2008 The Guava Authors
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  * http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.google.common.collect;
     18 
     19 import static com.google.common.base.Preconditions.checkNotNull;
     20 import static com.google.common.collect.Maps.safeContainsKey;
     21 import static com.google.common.collect.Maps.safeGet;
     22 
     23 import com.google.common.annotations.GwtCompatible;
     24 import com.google.common.base.Predicate;
     25 import com.google.common.base.Predicates;
     26 import com.google.common.base.Supplier;
     27 
     28 import java.io.Serializable;
     29 import java.util.AbstractCollection;
     30 import java.util.AbstractMap;
     31 import java.util.AbstractSet;
     32 import java.util.Collection;
     33 import java.util.Iterator;
     34 import java.util.LinkedHashMap;
     35 import java.util.Map;
     36 import java.util.Map.Entry;
     37 import java.util.Set;
     38 
     39 import javax.annotation.Nullable;
     40 
     41 /**
     42  * {@link Table} implementation backed by a map that associates row keys with
     43  * column key / value secondary maps. This class provides rapid access to
     44  * records by the row key alone or by both keys, but not by just the column key.
     45  *
     46  * <p>The views returned by {@link #column}, {@link #columnKeySet()}, and {@link
     47  * #columnMap()} have iterators that don't support {@code remove()}. Otherwise,
     48  * all optional operations are supported. Null row keys, columns keys, and
     49  * values are not supported.
     50  *
     51  * <p>Lookups by row key are often faster than lookups by column key, because
     52  * the data is stored in a {@code Map<R, Map<C, V>>}. A method call like {@code
     53  * column(columnKey).get(rowKey)} still runs quickly, since the row key is
     54  * provided. However, {@code column(columnKey).size()} takes longer, since an
     55  * iteration across all row keys occurs.
     56  *
     57  * <p>Note that this implementation is not synchronized. If multiple threads
     58  * access this table concurrently and one of the threads modifies the table, it
     59  * must be synchronized externally.
     60  *
     61  * @author Jared Levy
     62  */
     63 @GwtCompatible
     64 class StandardTable<R, C, V> implements Table<R, C, V>, Serializable {
     65   @GwtTransient final Map<R, Map<C, V>> backingMap;
     66   @GwtTransient final Supplier<? extends Map<C, V>> factory;
     67 
     68   StandardTable(Map<R, Map<C, V>> backingMap,
     69       Supplier<? extends Map<C, V>> factory) {
     70     this.backingMap = backingMap;
     71     this.factory = factory;
     72   }
     73 
     74   // Accessors
     75 
     76   @Override public boolean contains(
     77       @Nullable Object rowKey, @Nullable Object columnKey) {
     78     if ((rowKey == null) || (columnKey == null)) {
     79       return false;
     80     }
     81     Map<C, V> map = safeGet(backingMap, rowKey);
     82     return map != null && safeContainsKey(map, columnKey);
     83   }
     84 
     85   @Override public boolean containsColumn(@Nullable Object columnKey) {
     86     if (columnKey == null) {
     87       return false;
     88     }
     89     for (Map<C, V> map : backingMap.values()) {
     90       if (safeContainsKey(map, columnKey)) {
     91         return true;
     92       }
     93     }
     94     return false;
     95   }
     96 
     97   @Override public boolean containsRow(@Nullable Object rowKey) {
     98     return rowKey != null && safeContainsKey(backingMap, rowKey);
     99   }
    100 
    101   @Override public boolean containsValue(@Nullable Object value) {
    102     if (value == null) {
    103       return false;
    104     }
    105     for (Map<C, V> map : backingMap.values()) {
    106       if (map.containsValue(value)) {
    107         return true;
    108       }
    109     }
    110     return false;
    111   }
    112 
    113   @Override public V get(@Nullable Object rowKey, @Nullable Object columnKey) {
    114     if ((rowKey == null) || (columnKey == null)) {
    115       return null;
    116     }
    117     Map<C, V> map = safeGet(backingMap, rowKey);
    118     return map == null ? null : safeGet(map, columnKey);
    119   }
    120 
    121   @Override public boolean isEmpty() {
    122     return backingMap.isEmpty();
    123   }
    124 
    125   @Override public int size() {
    126     int size = 0;
    127     for (Map<C, V> map : backingMap.values()) {
    128       size += map.size();
    129     }
    130     return size;
    131   }
    132 
    133   @Override public boolean equals(@Nullable Object obj) {
    134     if (obj == this) {
    135       return true;
    136     }
    137     if (obj instanceof Table) {
    138       Table<?, ?, ?> other = (Table<?, ?, ?>) obj;
    139       return cellSet().equals(other.cellSet());
    140     }
    141     return false;
    142   }
    143 
    144   @Override public int hashCode() {
    145     return cellSet().hashCode();
    146   }
    147 
    148   /**
    149    * Returns the string representation {@code rowMap().toString()}.
    150    */
    151   @Override public String toString() {
    152     return rowMap().toString();
    153   }
    154 
    155   // Mutators
    156 
    157   @Override public void clear() {
    158     backingMap.clear();
    159   }
    160 
    161   private Map<C, V> getOrCreate(R rowKey) {
    162     Map<C, V> map = backingMap.get(rowKey);
    163     if (map == null) {
    164       map = factory.get();
    165       backingMap.put(rowKey, map);
    166     }
    167     return map;
    168   }
    169 
    170   @Override public V put(R rowKey, C columnKey, V value) {
    171     checkNotNull(rowKey);
    172     checkNotNull(columnKey);
    173     checkNotNull(value);
    174     return getOrCreate(rowKey).put(columnKey, value);
    175   }
    176 
    177   @Override public void putAll(
    178       Table<? extends R, ? extends C, ? extends V> table) {
    179     for (Cell<? extends R, ? extends C, ? extends V> cell : table.cellSet()) {
    180       put(cell.getRowKey(), cell.getColumnKey(), cell.getValue());
    181     }
    182   }
    183 
    184   @Override public V remove(
    185       @Nullable Object rowKey, @Nullable Object columnKey) {
    186     if ((rowKey == null) || (columnKey == null)) {
    187       return null;
    188     }
    189     Map<C, V> map = safeGet(backingMap, rowKey);
    190     if (map == null) {
    191       return null;
    192     }
    193     V value = map.remove(columnKey);
    194     if (map.isEmpty()) {
    195       backingMap.remove(rowKey);
    196     }
    197     return value;
    198   }
    199 
    200   private Map<R, V> removeColumn(Object column) {
    201     Map<R, V> output = new LinkedHashMap<R, V>();
    202     Iterator<Entry<R, Map<C, V>>> iterator
    203         = backingMap.entrySet().iterator();
    204     while (iterator.hasNext()) {
    205       Entry<R, Map<C, V>> entry = iterator.next();
    206       V value = entry.getValue().remove(column);
    207       if (value != null) {
    208         output.put(entry.getKey(), value);
    209         if (entry.getValue().isEmpty()) {
    210           iterator.remove();
    211         }
    212       }
    213     }
    214     return output;
    215   }
    216 
    217   private boolean containsMapping(
    218       Object rowKey, Object columnKey, Object value) {
    219     return value != null && value.equals(get(rowKey, columnKey));
    220   }
    221 
    222   /** Remove a row key / column key / value mapping, if present. */
    223   private boolean removeMapping(Object rowKey, Object columnKey, Object value) {
    224     if (containsMapping(rowKey, columnKey, value)) {
    225       remove(rowKey, columnKey);
    226       return true;
    227     }
    228     return false;
    229   }
    230 
    231   // Views
    232 
    233   /**
    234    * Abstract collection whose {@code isEmpty()} returns whether the table is
    235    * empty and whose {@code clear()} clears all table mappings.
    236    */
    237   private abstract class TableCollection<T> extends AbstractCollection<T> {
    238     @Override public boolean isEmpty() {
    239       return backingMap.isEmpty();
    240     }
    241 
    242     @Override public void clear() {
    243       backingMap.clear();
    244     }
    245   }
    246 
    247   /**
    248    * Abstract set whose {@code isEmpty()} returns whether the table is empty and
    249    * whose {@code clear()} clears all table mappings.
    250    */
    251   private abstract class TableSet<T> extends AbstractSet<T> {
    252     @Override public boolean isEmpty() {
    253       return backingMap.isEmpty();
    254     }
    255 
    256     @Override public void clear() {
    257       backingMap.clear();
    258     }
    259   }
    260 
    261   private transient CellSet cellSet;
    262 
    263   /**
    264    * {@inheritDoc}
    265    *
    266    * <p>The set's iterator traverses the mappings for the first row, the
    267    * mappings for the second row, and so on.
    268    *
    269    * <p>Each cell is an immutable snapshot of a row key / column key / value
    270    * mapping, taken at the time the cell is returned by a method call to the
    271    * set or its iterator.
    272    */
    273   @Override public Set<Cell<R, C, V>> cellSet() {
    274     CellSet result = cellSet;
    275     return (result == null) ? cellSet = new CellSet() : result;
    276   }
    277 
    278   private class CellSet extends TableSet<Cell<R, C, V>> {
    279     @Override public Iterator<Cell<R, C, V>> iterator() {
    280       return new CellIterator();
    281     }
    282 
    283     @Override public int size() {
    284       return StandardTable.this.size();
    285     }
    286 
    287     @Override public boolean contains(Object obj) {
    288       if (obj instanceof Cell) {
    289         Cell<?, ?, ?> cell = (Cell<?, ?, ?>) obj;
    290         return containsMapping(
    291             cell.getRowKey(), cell.getColumnKey(), cell.getValue());
    292       }
    293       return false;
    294     }
    295 
    296     @Override public boolean remove(Object obj) {
    297       if (obj instanceof Cell) {
    298         Cell<?, ?, ?> cell = (Cell<?, ?, ?>) obj;
    299         return removeMapping(
    300             cell.getRowKey(), cell.getColumnKey(), cell.getValue());
    301       }
    302       return false;
    303     }
    304   }
    305 
    306   private class CellIterator implements Iterator<Cell<R, C, V>> {
    307     final Iterator<Entry<R, Map<C, V>>> rowIterator
    308         = backingMap.entrySet().iterator();
    309     Entry<R, Map<C, V>> rowEntry;
    310     Iterator<Entry<C, V>> columnIterator
    311         = Iterators.emptyModifiableIterator();
    312 
    313     @Override public boolean hasNext() {
    314       return rowIterator.hasNext() || columnIterator.hasNext();
    315     }
    316 
    317     @Override public Cell<R, C, V> next() {
    318       if (!columnIterator.hasNext()) {
    319         rowEntry = rowIterator.next();
    320         columnIterator = rowEntry.getValue().entrySet().iterator();
    321       }
    322       Entry<C, V> columnEntry = columnIterator.next();
    323       return Tables.immutableCell(
    324           rowEntry.getKey(), columnEntry.getKey(), columnEntry.getValue());
    325     }
    326 
    327     @Override public void remove() {
    328       columnIterator.remove();
    329       if (rowEntry.getValue().isEmpty()) {
    330         rowIterator.remove();
    331       }
    332     }
    333   }
    334 
    335   @Override public Map<C, V> row(R rowKey) {
    336     return new Row(rowKey);
    337   }
    338 
    339   class Row extends AbstractMap<C, V> {
    340     final R rowKey;
    341 
    342     Row(R rowKey) {
    343       this.rowKey = checkNotNull(rowKey);
    344     }
    345 
    346     Map<C, V> backingRowMap;
    347 
    348     Map<C, V> backingRowMap() {
    349       return (backingRowMap == null
    350               || (backingRowMap.isEmpty() && backingMap.containsKey(rowKey)))
    351           ? backingRowMap = computeBackingRowMap()
    352           : backingRowMap;
    353     }
    354 
    355     Map<C, V> computeBackingRowMap() {
    356       return backingMap.get(rowKey);
    357     }
    358 
    359     // Call this every time we perform a removal.
    360     void maintainEmptyInvariant() {
    361       if (backingRowMap() != null && backingRowMap.isEmpty()) {
    362         backingMap.remove(rowKey);
    363         backingRowMap = null;
    364       }
    365     }
    366 
    367     @Override
    368     public boolean containsKey(Object key) {
    369       Map<C, V> backingRowMap = backingRowMap();
    370       return (key != null && backingRowMap != null)
    371           && Maps.safeContainsKey(backingRowMap, key);
    372     }
    373 
    374     @Override
    375     public V get(Object key) {
    376       Map<C, V> backingRowMap = backingRowMap();
    377       return (key != null && backingRowMap != null)
    378           ? Maps.safeGet(backingRowMap, key)
    379           : null;
    380     }
    381 
    382     @Override
    383     public V put(C key, V value) {
    384       checkNotNull(key);
    385       checkNotNull(value);
    386       if (backingRowMap != null && !backingRowMap.isEmpty()) {
    387         return backingRowMap.put(key, value);
    388       }
    389       return StandardTable.this.put(rowKey, key, value);
    390     }
    391 
    392     @Override
    393     public V remove(Object key) {
    394       try {
    395         Map<C, V> backingRowMap = backingRowMap();
    396         if (backingRowMap == null) {
    397           return null;
    398         }
    399         V result = backingRowMap.remove(key);
    400         maintainEmptyInvariant();
    401         return result;
    402       } catch (ClassCastException e) {
    403         return null;
    404       }
    405     }
    406 
    407     @Override
    408     public void clear() {
    409       Map<C, V> backingRowMap = backingRowMap();
    410       if (backingRowMap != null) {
    411         backingRowMap.clear();
    412       }
    413       maintainEmptyInvariant();
    414     }
    415 
    416     Set<C> keySet;
    417 
    418     @Override
    419     public Set<C> keySet() {
    420       Set<C> result = keySet;
    421       if (result == null) {
    422         return keySet = new Maps.KeySet<C, V>() {
    423           @Override
    424           Map<C, V> map() {
    425             return Row.this;
    426           }
    427         };
    428       }
    429       return result;
    430     }
    431 
    432     Set<Entry<C, V>> entrySet;
    433 
    434     @Override
    435     public Set<Entry<C, V>> entrySet() {
    436       Set<Entry<C, V>> result = entrySet;
    437       if (result == null) {
    438         return entrySet = new RowEntrySet();
    439       }
    440       return result;
    441     }
    442 
    443     private class RowEntrySet extends Maps.EntrySet<C, V> {
    444       @Override
    445       Map<C, V> map() {
    446         return Row.this;
    447       }
    448 
    449       @Override
    450       public int size() {
    451         Map<C, V> map = backingRowMap();
    452         return (map == null) ? 0 : map.size();
    453       }
    454 
    455       @Override
    456       public Iterator<Entry<C, V>> iterator() {
    457         final Map<C, V> map = backingRowMap();
    458         if (map == null) {
    459           return Iterators.emptyModifiableIterator();
    460         }
    461         final Iterator<Entry<C, V>> iterator = map.entrySet().iterator();
    462         return new Iterator<Entry<C, V>>() {
    463           @Override public boolean hasNext() {
    464             return iterator.hasNext();
    465           }
    466           @Override public Entry<C, V> next() {
    467             final Entry<C, V> entry = iterator.next();
    468             return new ForwardingMapEntry<C, V>() {
    469               @Override protected Entry<C, V> delegate() {
    470                 return entry;
    471               }
    472               @Override public V setValue(V value) {
    473                 return super.setValue(checkNotNull(value));
    474               }
    475               @Override
    476               public boolean equals(Object object) {
    477                 // TODO(user): identify why this affects GWT tests
    478                 return standardEquals(object);
    479               }
    480             };
    481           }
    482 
    483           @Override
    484           public void remove() {
    485             iterator.remove();
    486             maintainEmptyInvariant();
    487           }
    488         };
    489       }
    490     }
    491   }
    492 
    493   /**
    494    * {@inheritDoc}
    495    *
    496    * <p>The returned map's views have iterators that don't support
    497    * {@code remove()}.
    498    */
    499   @Override public Map<R, V> column(C columnKey) {
    500     return new Column(columnKey);
    501   }
    502 
    503   private class Column extends Maps.ImprovedAbstractMap<R, V> {
    504     final C columnKey;
    505 
    506     Column(C columnKey) {
    507       this.columnKey = checkNotNull(columnKey);
    508     }
    509 
    510     @Override public V put(R key, V value) {
    511       return StandardTable.this.put(key, columnKey, value);
    512     }
    513 
    514     @Override public V get(Object key) {
    515       return StandardTable.this.get(key, columnKey);
    516     }
    517 
    518     @Override public boolean containsKey(Object key) {
    519       return StandardTable.this.contains(key, columnKey);
    520     }
    521 
    522     @Override public V remove(Object key) {
    523       return StandardTable.this.remove(key, columnKey);
    524     }
    525 
    526     @Override public Set<Entry<R, V>> createEntrySet() {
    527       return new EntrySet();
    528     }
    529 
    530     Values columnValues;
    531 
    532     @Override public Collection<V> values() {
    533       Values result = columnValues;
    534       return (result == null) ? columnValues = new Values() : result;
    535     }
    536 
    537     /**
    538      * Removes all {@code Column} mappings whose row key and value satisfy the
    539      * given predicate.
    540      */
    541     boolean removePredicate(Predicate<? super Entry<R, V>> predicate) {
    542       boolean changed = false;
    543       Iterator<Entry<R, Map<C, V>>> iterator
    544           = backingMap.entrySet().iterator();
    545       while (iterator.hasNext()) {
    546         Entry<R, Map<C, V>> entry = iterator.next();
    547         Map<C, V> map = entry.getValue();
    548         V value = map.get(columnKey);
    549         if (value != null
    550             && predicate.apply(
    551                 new ImmutableEntry<R, V>(entry.getKey(), value))) {
    552           map.remove(columnKey);
    553           changed = true;
    554           if (map.isEmpty()) {
    555             iterator.remove();
    556           }
    557         }
    558       }
    559       return changed;
    560     }
    561 
    562     class EntrySet extends AbstractSet<Entry<R, V>> {
    563       @Override public Iterator<Entry<R, V>> iterator() {
    564         return new EntrySetIterator();
    565       }
    566 
    567       @Override public int size() {
    568         int size = 0;
    569         for (Map<C, V> map : backingMap.values()) {
    570           if (map.containsKey(columnKey)) {
    571             size++;
    572           }
    573         }
    574         return size;
    575       }
    576 
    577       @Override public boolean isEmpty() {
    578         return !containsColumn(columnKey);
    579       }
    580 
    581       @Override public void clear() {
    582         Predicate<Entry<R, V>> predicate = Predicates.alwaysTrue();
    583         removePredicate(predicate);
    584       }
    585 
    586       @Override public boolean contains(Object o) {
    587         if (o instanceof Entry) {
    588           Entry<?, ?> entry = (Entry<?, ?>) o;
    589           return containsMapping(entry.getKey(), columnKey, entry.getValue());
    590         }
    591         return false;
    592       }
    593 
    594       @Override public boolean remove(Object obj) {
    595         if (obj instanceof Entry) {
    596           Entry<?, ?> entry = (Entry<?, ?>) obj;
    597           return removeMapping(entry.getKey(), columnKey, entry.getValue());
    598         }
    599         return false;
    600       }
    601 
    602       @Override public boolean removeAll(Collection<?> c) {
    603         boolean changed = false;
    604         for (Object obj : c) {
    605           changed |= remove(obj);
    606         }
    607         return changed;
    608       }
    609 
    610       @Override public boolean retainAll(Collection<?> c) {
    611         return removePredicate(Predicates.not(Predicates.in(c)));
    612       }
    613     }
    614 
    615     class EntrySetIterator extends AbstractIterator<Entry<R, V>> {
    616       final Iterator<Entry<R, Map<C, V>>> iterator
    617           = backingMap.entrySet().iterator();
    618       @Override protected Entry<R, V> computeNext() {
    619         while (iterator.hasNext()) {
    620           final Entry<R, Map<C, V>> entry = iterator.next();
    621           if (entry.getValue().containsKey(columnKey)) {
    622             return new AbstractMapEntry<R, V>() {
    623               @Override public R getKey() {
    624                 return entry.getKey();
    625               }
    626               @Override public V getValue() {
    627                 return entry.getValue().get(columnKey);
    628               }
    629               @Override public V setValue(V value) {
    630                 return entry.getValue().put(columnKey, checkNotNull(value));
    631               }
    632             };
    633           }
    634         }
    635         return endOfData();
    636       }
    637     }
    638 
    639     KeySet keySet;
    640 
    641     @Override public Set<R> keySet() {
    642       KeySet result = keySet;
    643       return result == null ? keySet = new KeySet() : result;
    644     }
    645 
    646     class KeySet extends AbstractSet<R> {
    647       @Override public Iterator<R> iterator() {
    648         return keyIteratorImpl(Column.this);
    649       }
    650 
    651       @Override public int size() {
    652         return entrySet().size();
    653       }
    654 
    655       @Override public boolean isEmpty() {
    656         return !containsColumn(columnKey);
    657       }
    658 
    659       @Override public boolean contains(Object obj) {
    660         return StandardTable.this.contains(obj, columnKey);
    661       }
    662 
    663       @Override public boolean remove(Object obj) {
    664         return StandardTable.this.remove(obj, columnKey) != null;
    665       }
    666 
    667       @Override public void clear() {
    668         entrySet().clear();
    669       }
    670 
    671       @Override public boolean removeAll(final Collection<?> c) {
    672         boolean changed = false;
    673         for (Object obj : c) {
    674           changed |= remove(obj);
    675         }
    676         return changed;
    677       }
    678 
    679       @Override public boolean retainAll(final Collection<?> c) {
    680         checkNotNull(c);
    681         Predicate<Entry<R, V>> predicate = new Predicate<Entry<R, V>>() {
    682           @Override
    683           public boolean apply(Entry<R, V> entry) {
    684             return !c.contains(entry.getKey());
    685           }
    686         };
    687         return removePredicate(predicate);
    688       }
    689     }
    690 
    691     class Values extends AbstractCollection<V> {
    692       @Override public Iterator<V> iterator() {
    693         return valueIteratorImpl(Column.this);
    694       }
    695 
    696       @Override public int size() {
    697         return entrySet().size();
    698       }
    699 
    700       @Override public boolean isEmpty() {
    701         return !containsColumn(columnKey);
    702       }
    703 
    704       @Override public void clear() {
    705         entrySet().clear();
    706       }
    707 
    708       @Override public boolean remove(Object obj) {
    709         if (obj == null) {
    710           return false;
    711         }
    712         Iterator<Map<C, V>> iterator = backingMap.values().iterator();
    713         while (iterator.hasNext()) {
    714           Map<C, V> map = iterator.next();
    715           if (map.entrySet().remove(
    716               new ImmutableEntry<C, Object>(columnKey, obj))) {
    717             if (map.isEmpty()) {
    718               iterator.remove();
    719             }
    720             return true;
    721           }
    722         }
    723         return false;
    724       }
    725 
    726       @Override public boolean removeAll(final Collection<?> c) {
    727         checkNotNull(c);
    728         Predicate<Entry<R, V>> predicate = new Predicate<Entry<R, V>>() {
    729           @Override
    730           public boolean apply(Entry<R, V> entry) {
    731             return c.contains(entry.getValue());
    732           }
    733         };
    734         return removePredicate(predicate);
    735       }
    736 
    737       @Override public boolean retainAll(final Collection<?> c) {
    738         checkNotNull(c);
    739         Predicate<Entry<R, V>> predicate = new Predicate<Entry<R, V>>() {
    740           @Override
    741           public boolean apply(Entry<R, V> entry) {
    742             return !c.contains(entry.getValue());
    743           }
    744         };
    745         return removePredicate(predicate);
    746       }
    747     }
    748   }
    749 
    750   private transient RowKeySet rowKeySet;
    751 
    752   @Override public Set<R> rowKeySet() {
    753     Set<R> result = rowKeySet;
    754     return (result == null) ? rowKeySet = new RowKeySet() : result;
    755   }
    756 
    757   class RowKeySet extends TableSet<R> {
    758     @Override public Iterator<R> iterator() {
    759       return keyIteratorImpl(rowMap());
    760     }
    761 
    762     @Override public int size() {
    763       return backingMap.size();
    764     }
    765 
    766     @Override public boolean contains(Object obj) {
    767       return containsRow(obj);
    768     }
    769 
    770     @Override public boolean remove(Object obj) {
    771       return (obj != null) && backingMap.remove(obj) != null;
    772     }
    773   }
    774 
    775   private transient Set<C> columnKeySet;
    776 
    777   /**
    778    * {@inheritDoc}
    779    *
    780    * <p>The returned set has an iterator that does not support {@code remove()}.
    781    *
    782    * <p>The set's iterator traverses the columns of the first row, the
    783    * columns of the second row, etc., skipping any columns that have
    784    * appeared previously.
    785    */
    786   @Override
    787   public Set<C> columnKeySet() {
    788     Set<C> result = columnKeySet;
    789     return (result == null) ? columnKeySet = new ColumnKeySet() : result;
    790   }
    791 
    792   private class ColumnKeySet extends TableSet<C> {
    793     @Override public Iterator<C> iterator() {
    794       return createColumnKeyIterator();
    795     }
    796 
    797     @Override public int size() {
    798       return Iterators.size(iterator());
    799     }
    800 
    801     @Override public boolean remove(Object obj) {
    802       if (obj == null) {
    803         return false;
    804       }
    805       boolean changed = false;
    806       Iterator<Map<C, V>> iterator = backingMap.values().iterator();
    807       while (iterator.hasNext()) {
    808         Map<C, V> map = iterator.next();
    809         if (map.keySet().remove(obj)) {
    810           changed = true;
    811           if (map.isEmpty()) {
    812             iterator.remove();
    813           }
    814         }
    815       }
    816       return changed;
    817     }
    818 
    819     @Override public boolean removeAll(Collection<?> c) {
    820       checkNotNull(c);
    821       boolean changed = false;
    822       Iterator<Map<C, V>> iterator = backingMap.values().iterator();
    823       while (iterator.hasNext()) {
    824         Map<C, V> map = iterator.next();
    825         // map.keySet().removeAll(c) can throw a NPE when map is a TreeMap with
    826         // natural ordering and c contains a null.
    827         if (Iterators.removeAll(map.keySet().iterator(), c)) {
    828           changed = true;
    829           if (map.isEmpty()) {
    830             iterator.remove();
    831           }
    832         }
    833       }
    834       return changed;
    835     }
    836 
    837     @Override public boolean retainAll(Collection<?> c) {
    838       checkNotNull(c);
    839       boolean changed = false;
    840       Iterator<Map<C, V>> iterator = backingMap.values().iterator();
    841       while (iterator.hasNext()) {
    842         Map<C, V> map = iterator.next();
    843         if (map.keySet().retainAll(c)) {
    844           changed = true;
    845           if (map.isEmpty()) {
    846             iterator.remove();
    847           }
    848         }
    849       }
    850       return changed;
    851     }
    852 
    853     @Override public boolean contains(Object obj) {
    854       if (obj == null) {
    855         return false;
    856       }
    857       for (Map<C, V> map : backingMap.values()) {
    858         if (map.containsKey(obj)) {
    859           return true;
    860         }
    861       }
    862       return false;
    863     }
    864   }
    865 
    866   /**
    867    * Creates an iterator that returns each column value with duplicates
    868    * omitted.
    869    */
    870   Iterator<C> createColumnKeyIterator() {
    871     return new ColumnKeyIterator();
    872   }
    873 
    874   private class ColumnKeyIterator extends AbstractIterator<C> {
    875     // Use the same map type to support TreeMaps with comparators that aren't
    876     // consistent with equals().
    877     final Map<C, V> seen = factory.get();
    878     final Iterator<Map<C, V>> mapIterator = backingMap.values().iterator();
    879     Iterator<Entry<C, V>> entryIterator = Iterators.emptyIterator();
    880 
    881     @Override protected C computeNext() {
    882       while (true) {
    883         if (entryIterator.hasNext()) {
    884           Entry<C, V> entry = entryIterator.next();
    885           if (!seen.containsKey(entry.getKey())) {
    886             seen.put(entry.getKey(), entry.getValue());
    887             return entry.getKey();
    888           }
    889         } else if (mapIterator.hasNext()) {
    890           entryIterator = mapIterator.next().entrySet().iterator();
    891         } else {
    892           return endOfData();
    893         }
    894       }
    895     }
    896   }
    897 
    898   private transient Values values;
    899 
    900   /**
    901    * {@inheritDoc}
    902    *
    903    * <p>The collection's iterator traverses the values for the first row,
    904    * the values for the second row, and so on.
    905    */
    906   @Override public Collection<V> values() {
    907     Values result = values;
    908     return (result == null) ? values = new Values() : result;
    909   }
    910 
    911   private class Values extends TableCollection<V> {
    912     @Override public Iterator<V> iterator() {
    913       final Iterator<Cell<R, C, V>> cellIterator = cellSet().iterator();
    914       return new Iterator<V>() {
    915         @Override public boolean hasNext() {
    916           return cellIterator.hasNext();
    917         }
    918         @Override public V next() {
    919           return cellIterator.next().getValue();
    920         }
    921         @Override public void remove() {
    922           cellIterator.remove();
    923         }
    924       };
    925     }
    926 
    927     @Override public int size() {
    928       return StandardTable.this.size();
    929     }
    930   }
    931 
    932   private transient RowMap rowMap;
    933 
    934   @Override public Map<R, Map<C, V>> rowMap() {
    935     RowMap result = rowMap;
    936     return (result == null) ? rowMap = new RowMap() : result;
    937   }
    938 
    939   class RowMap extends Maps.ImprovedAbstractMap<R, Map<C, V>> {
    940     @Override public boolean containsKey(Object key) {
    941       return containsRow(key);
    942     }
    943 
    944     // performing cast only when key is in backing map and has the correct type
    945     @SuppressWarnings("unchecked")
    946     @Override public Map<C, V> get(Object key) {
    947       return containsRow(key) ? row((R) key) : null;
    948     }
    949 
    950     @Override public Set<R> keySet() {
    951       return rowKeySet();
    952     }
    953 
    954     @Override public Map<C, V> remove(Object key) {
    955       return (key == null) ? null : backingMap.remove(key);
    956     }
    957 
    958     @Override protected Set<Entry<R, Map<C, V>>> createEntrySet() {
    959       return new EntrySet();
    960     }
    961 
    962     class EntrySet extends TableSet<Entry<R, Map<C, V>>> {
    963       @Override public Iterator<Entry<R, Map<C, V>>> iterator() {
    964         return new EntryIterator();
    965       }
    966 
    967       @Override public int size() {
    968         return backingMap.size();
    969       }
    970 
    971       @Override public boolean contains(Object obj) {
    972         if (obj instanceof Entry) {
    973           Entry<?, ?> entry = (Entry<?, ?>) obj;
    974           return entry.getKey() != null
    975               && entry.getValue() instanceof Map
    976               && Collections2.safeContains(backingMap.entrySet(), entry);
    977         }
    978         return false;
    979       }
    980 
    981       @Override public boolean remove(Object obj) {
    982         if (obj instanceof Entry) {
    983           Entry<?, ?> entry = (Entry<?, ?>) obj;
    984           return entry.getKey() != null
    985               && entry.getValue() instanceof Map
    986               && backingMap.entrySet().remove(entry);
    987         }
    988         return false;
    989       }
    990     }
    991 
    992     class EntryIterator implements Iterator<Entry<R, Map<C, V>>> {
    993       final Iterator<R> delegate = backingMap.keySet().iterator();
    994 
    995       @Override public boolean hasNext() {
    996         return delegate.hasNext();
    997       }
    998 
    999       @Override public Entry<R, Map<C, V>> next() {
   1000         R rowKey = delegate.next();
   1001         return new ImmutableEntry<R, Map<C, V>>(rowKey, row(rowKey));
   1002       }
   1003 
   1004       @Override public void remove() {
   1005         delegate.remove();
   1006       }
   1007     }
   1008   }
   1009 
   1010   private transient ColumnMap columnMap;
   1011 
   1012   @Override public Map<C, Map<R, V>> columnMap() {
   1013     ColumnMap result = columnMap;
   1014     return (result == null) ? columnMap = new ColumnMap() : result;
   1015   }
   1016 
   1017   private class ColumnMap extends Maps.ImprovedAbstractMap<C, Map<R, V>> {
   1018     // The cast to C occurs only when the key is in the map, implying that it
   1019     // has the correct type.
   1020     @SuppressWarnings("unchecked")
   1021     @Override public Map<R, V> get(Object key) {
   1022       return containsColumn(key) ? column((C) key) : null;
   1023     }
   1024 
   1025     @Override public boolean containsKey(Object key) {
   1026       return containsColumn(key);
   1027     }
   1028 
   1029     @Override public Map<R, V> remove(Object key) {
   1030       return containsColumn(key) ? removeColumn(key) : null;
   1031     }
   1032 
   1033     @Override public Set<Entry<C, Map<R, V>>> createEntrySet() {
   1034       return new ColumnMapEntrySet();
   1035     }
   1036 
   1037     @Override public Set<C> keySet() {
   1038       return columnKeySet();
   1039     }
   1040 
   1041     ColumnMapValues columnMapValues;
   1042 
   1043     @Override public Collection<Map<R, V>> values() {
   1044       ColumnMapValues result = columnMapValues;
   1045       return
   1046           (result == null) ? columnMapValues = new ColumnMapValues() : result;
   1047     }
   1048 
   1049     class ColumnMapEntrySet extends TableSet<Entry<C, Map<R, V>>> {
   1050       @Override public Iterator<Entry<C, Map<R, V>>> iterator() {
   1051         final Iterator<C> columnIterator = columnKeySet().iterator();
   1052         return new UnmodifiableIterator<Entry<C, Map<R, V>>>() {
   1053           @Override public boolean hasNext() {
   1054             return columnIterator.hasNext();
   1055           }
   1056           @Override public Entry<C, Map<R, V>> next() {
   1057             C columnKey = columnIterator.next();
   1058             return new ImmutableEntry<C, Map<R, V>>(
   1059                 columnKey, column(columnKey));
   1060           }
   1061         };
   1062       }
   1063 
   1064       @Override public int size() {
   1065         return columnKeySet().size();
   1066       }
   1067 
   1068       @Override public boolean contains(Object obj) {
   1069         if (obj instanceof Entry) {
   1070           Entry<?, ?> entry = (Entry<?, ?>) obj;
   1071           if (containsColumn(entry.getKey())) {
   1072             // The cast to C occurs only when the key is in the map, implying
   1073             // that it has the correct type.
   1074             @SuppressWarnings("unchecked")
   1075             C columnKey = (C) entry.getKey();
   1076             return get(columnKey).equals(entry.getValue());
   1077           }
   1078         }
   1079         return false;
   1080       }
   1081 
   1082       @Override public boolean remove(Object obj) {
   1083         if (contains(obj)) {
   1084           Entry<?, ?> entry = (Entry<?, ?>) obj;
   1085           removeColumn(entry.getKey());
   1086           return true;
   1087         }
   1088         return false;
   1089       }
   1090 
   1091       @Override public boolean removeAll(Collection<?> c) {
   1092         boolean changed = false;
   1093         for (Object obj : c) {
   1094           changed |= remove(obj);
   1095         }
   1096         return changed;
   1097       }
   1098 
   1099       @Override public boolean retainAll(Collection<?> c) {
   1100         boolean changed = false;
   1101         for (C columnKey : Lists.newArrayList(columnKeySet().iterator())) {
   1102           if (!c.contains(new ImmutableEntry<C, Map<R, V>>(
   1103               columnKey, column(columnKey)))) {
   1104             removeColumn(columnKey);
   1105             changed = true;
   1106           }
   1107         }
   1108         return changed;
   1109       }
   1110     }
   1111 
   1112     private class ColumnMapValues extends TableCollection<Map<R, V>> {
   1113       @Override public Iterator<Map<R, V>> iterator() {
   1114         return valueIteratorImpl(ColumnMap.this);
   1115       }
   1116 
   1117       @Override public boolean remove(Object obj) {
   1118         for (Entry<C, Map<R, V>> entry : ColumnMap.this.entrySet()) {
   1119           if (entry.getValue().equals(obj)) {
   1120             removeColumn(entry.getKey());
   1121             return true;
   1122           }
   1123         }
   1124         return false;
   1125       }
   1126 
   1127       @Override public boolean removeAll(Collection<?> c) {
   1128         checkNotNull(c);
   1129         boolean changed = false;
   1130         for (C columnKey : Lists.newArrayList(columnKeySet().iterator())) {
   1131           if (c.contains(column(columnKey))) {
   1132             removeColumn(columnKey);
   1133             changed = true;
   1134           }
   1135         }
   1136         return changed;
   1137       }
   1138 
   1139       @Override public boolean retainAll(Collection<?> c) {
   1140         checkNotNull(c);
   1141         boolean changed = false;
   1142         for (C columnKey : Lists.newArrayList(columnKeySet().iterator())) {
   1143           if (!c.contains(column(columnKey))) {
   1144             removeColumn(columnKey);
   1145             changed = true;
   1146           }
   1147         }
   1148         return changed;
   1149       }
   1150 
   1151       @Override public int size() {
   1152         return columnKeySet().size();
   1153       }
   1154     }
   1155   }
   1156 
   1157   private static final long serialVersionUID = 0;
   1158 
   1159   // TODO(kevinb): Move keyIteratorImpl and valueIteratorImpl to Maps, reuse
   1160 
   1161   /**
   1162    * Generates the iterator of a map's key set from the map's entry set
   1163    * iterator.
   1164    */
   1165   static <K, V> Iterator<K> keyIteratorImpl(Map<K, V> map) {
   1166     final Iterator<Entry<K, V>> entryIterator = map.entrySet().iterator();
   1167     return new Iterator<K>() {
   1168       @Override public boolean hasNext() {
   1169         return entryIterator.hasNext();
   1170       }
   1171       @Override public K next() {
   1172         return entryIterator.next().getKey();
   1173       }
   1174       @Override public void remove() {
   1175         entryIterator.remove();
   1176       }
   1177     };
   1178   }
   1179 
   1180   /**
   1181    * Generates the iterator of a map's value collection from the map's entry set
   1182    * iterator.
   1183    */
   1184   static <K, V> Iterator<V> valueIteratorImpl(Map<K, V> map) {
   1185     final Iterator<Entry<K, V>> entryIterator = map.entrySet().iterator();
   1186     return new Iterator<V>() {
   1187       @Override public boolean hasNext() {
   1188         return entryIterator.hasNext();
   1189       }
   1190       @Override public V next() {
   1191         return entryIterator.next().getValue();
   1192       }
   1193       @Override public void remove() {
   1194         entryIterator.remove();
   1195       }
   1196     };
   1197   }
   1198 }
   1199