11d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert/*
21d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Copyright (C) 2008 The Guava Authors
31d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *
41d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Licensed under the Apache License, Version 2.0 (the "License");
51d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * you may not use this file except in compliance with the License.
61d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * You may obtain a copy of the License at
71d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *
81d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * http://www.apache.org/licenses/LICENSE-2.0
91d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *
101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Unless required by applicable law or agreed to in writing, software
111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * distributed under the License is distributed on an "AS IS" BASIS,
121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * See the License for the specific language governing permissions and
141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * limitations under the License.
151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */
161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertpackage com.google.common.collect;
181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport static com.google.common.base.Preconditions.checkArgument;
201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport static com.google.common.base.Preconditions.checkNotNull;
211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.annotations.Beta;
231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.annotations.GwtCompatible;
241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.base.Function;
251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.base.Objects;
261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.base.Supplier;
271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.collect.Collections2.TransformedCollection;
281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.collect.Table.Cell;
291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.io.Serializable;
311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.Collection;
321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.Collections;
331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.Map;
341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.Set;
351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.SortedMap;
361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.SortedSet;
371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport javax.annotation.Nullable;
391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert/**
411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Provides static methods that involve a {@code Table}.
421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *
431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @author Jared Levy
441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @author Louis Wasserman
451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @since 7.0
461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */
471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert@GwtCompatible
481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert@Beta
491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertpublic final class Tables {
501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  private Tables() {}
511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /**
531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * Returns an immutable cell with the specified row key, column key, and
541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * value.
551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * <p>The returned cell is serializable.
571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * @param rowKey the row key to be associated with the returned cell
591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * @param columnKey the column key to be associated with the returned cell
601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * @param value the value to be associated with the returned cell
611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   */
621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public static <R, C, V> Cell<R, C, V> immutableCell(
631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      @Nullable R rowKey, @Nullable C columnKey, @Nullable V value) {
641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    return new ImmutableCell<R, C, V>(rowKey, columnKey, value);
651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  static final class ImmutableCell<R, C, V>
681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      extends AbstractCell<R, C, V> implements Serializable {
691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    private final R rowKey;
701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    private final C columnKey;
711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    private final V value;
721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    ImmutableCell(
741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        @Nullable R rowKey, @Nullable C columnKey, @Nullable V value) {
751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      this.rowKey = rowKey;
761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      this.columnKey = columnKey;
771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      this.value = value;
781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override
811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    public R getRowKey() {
821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return rowKey;
831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override
851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    public C getColumnKey() {
861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return columnKey;
871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override
891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    public V getValue() {
901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return value;
911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    private static final long serialVersionUID = 0;
941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  abstract static class AbstractCell<R, C, V> implements Cell<R, C, V> {
971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    // needed for serialization
981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    AbstractCell() {}
991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public boolean equals(Object obj) {
1011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      if (obj == this) {
1021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        return true;
1031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
1041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      if (obj instanceof Cell) {
1051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        Cell<?, ?, ?> other = (Cell<?, ?, ?>) obj;
1061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        return Objects.equal(getRowKey(), other.getRowKey())
1071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert            && Objects.equal(getColumnKey(), other.getColumnKey())
1081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert            && Objects.equal(getValue(), other.getValue());
1091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
1101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return false;
1111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
1121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public int hashCode() {
1141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return Objects.hashCode(getRowKey(), getColumnKey(), getValue());
1151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
1161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public String toString() {
1181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return "(" + getRowKey() + "," + getColumnKey() + ")=" + getValue();
1191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
1201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
1211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /**
1231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * Creates a transposed view of a given table that flips its row and column
1241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * keys. In other words, calling {@code get(columnKey, rowKey)} on the
1251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * generated table always returns the same value as calling {@code
1261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * get(rowKey, columnKey)} on the original table. Updating the original table
1271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * changes the contents of the transposed table and vice versa.
1281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
1291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * <p>The returned table supports update operations as long as the input table
1301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * supports the analogous operation with swapped rows and columns. For
1311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * example, in a {@link HashBasedTable} instance, {@code
1321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * rowKeySet().iterator()} supports {@code remove()} but {@code
1331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * columnKeySet().iterator()} doesn't. With a transposed {@link
1341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * HashBasedTable}, it's the other way around.
1351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   */
1361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public static <R, C, V> Table<C, R, V> transpose(Table<R, C, V> table) {
1371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    return (table instanceof TransposeTable)
1381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        ? ((TransposeTable<R, C, V>) table).original
1391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        : new TransposeTable<C, R, V>(table);
1401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
1411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  private static class TransposeTable<C, R, V> implements Table<C, R, V> {
1431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    final Table<R, C, V> original;
1441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    TransposeTable(Table<R, C, V> original) {
1461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      this.original = checkNotNull(original);
1471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
1481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override
1501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    public void clear() {
1511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      original.clear();
1521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
1531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override
1551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    public Map<C, V> column(R columnKey) {
1561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return original.row(columnKey);
1571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
1581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override
1601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    public Set<R> columnKeySet() {
1611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return original.rowKeySet();
1621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
1631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override
1651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    public Map<R, Map<C, V>> columnMap() {
1661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return original.rowMap();
1671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
1681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override
1701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    public boolean contains(
1711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        @Nullable Object rowKey, @Nullable Object columnKey) {
1721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return original.contains(columnKey, rowKey);
1731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
1741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override
1761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    public boolean containsColumn(@Nullable Object columnKey) {
1771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return original.containsRow(columnKey);
1781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
1791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override
1811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    public boolean containsRow(@Nullable Object rowKey) {
1821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return original.containsColumn(rowKey);
1831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
1841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override
1861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    public boolean containsValue(@Nullable Object value) {
1871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return original.containsValue(value);
1881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
1891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override
1911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    public V get(@Nullable Object rowKey, @Nullable Object columnKey) {
1921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return original.get(columnKey, rowKey);
1931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
1941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override
1961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    public boolean isEmpty() {
1971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return original.isEmpty();
1981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
1991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override
2011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    public V put(C rowKey, R columnKey, V value) {
2021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return original.put(columnKey, rowKey, value);
2031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
2041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override
2061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    public void putAll(Table<? extends C, ? extends R, ? extends V> table) {
2071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      original.putAll(transpose(table));
2081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
2091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override
2111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    public V remove(@Nullable Object rowKey, @Nullable Object columnKey) {
2121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return original.remove(columnKey, rowKey);
2131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
2141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override
2161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    public Map<R, V> row(C rowKey) {
2171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return original.column(rowKey);
2181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
2191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override
2211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    public Set<C> rowKeySet() {
2221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return original.columnKeySet();
2231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
2241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override
2261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    public Map<C, Map<R, V>> rowMap() {
2271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return original.columnMap();
2281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
2291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override
2311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    public int size() {
2321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return original.size();
2331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
2341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override
2361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    public Collection<V> values() {
2371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return original.values();
2381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
2391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public boolean equals(@Nullable Object obj) {
2411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      if (obj == this) {
2421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        return true;
2431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
2441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      if (obj instanceof Table) {
2451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        Table<?, ?, ?> other = (Table<?, ?, ?>) obj;
2461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        return cellSet().equals(other.cellSet());
2471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
2481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return false;
2491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
2501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public int hashCode() {
2521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return cellSet().hashCode();
2531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
2541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public String toString() {
2561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return rowMap().toString();
2571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
2581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    // Will cast TRANSPOSE_CELL to a type that always succeeds
2601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    private static final Function<Cell<?, ?, ?>, Cell<?, ?, ?>> TRANSPOSE_CELL =
2611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        new Function<Cell<?, ?, ?>, Cell<?, ?, ?>>() {
2621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          @Override
2631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          public Cell<?, ?, ?> apply(Cell<?, ?, ?> cell) {
2641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert            return immutableCell(
2651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert                cell.getColumnKey(), cell.getRowKey(), cell.getValue());
2661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          }
2671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        };
2681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    CellSet cellSet;
2701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override
2721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    public Set<Cell<C, R, V>> cellSet() {
2731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      CellSet result = cellSet;
2741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return (result == null) ? cellSet = new CellSet() : result;
2751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
2761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    class CellSet extends TransformedCollection<Cell<R, C, V>, Cell<C, R, V>>
2781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        implements Set<Cell<C, R, V>> {
2791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      // Casting TRANSPOSE_CELL to a type that always succeeds
2801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      @SuppressWarnings("unchecked")
2811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      CellSet() {
2821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        super(original.cellSet(), (Function) TRANSPOSE_CELL);
2831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
2841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      @Override public boolean equals(Object obj) {
2861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        if (obj == this) {
2871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          return true;
2881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        }
2891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        if (!(obj instanceof Set)) {
2901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          return false;
2911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        }
2921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        Set<?> os = (Set<?>) obj;
2931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        if (os.size() != size()) {
2941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          return false;
2951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        }
2961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        return containsAll(os);
2971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
2981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      @Override public int hashCode() {
3001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        return Sets.hashCodeImpl(this);
3011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
3021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
3031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      @Override public boolean contains(Object obj) {
3041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        if (obj instanceof Cell) {
3051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          Cell<?, ?, ?> cell = (Cell<?, ?, ?>) obj;
3061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          return original.cellSet().contains(immutableCell(
3071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert              cell.getColumnKey(), cell.getRowKey(), cell.getValue()));
3081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        }
3091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        return false;
3101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
3111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
3121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      @Override public boolean remove(Object obj) {
3131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        if (obj instanceof Cell) {
3141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          Cell<?, ?, ?> cell = (Cell<?, ?, ?>) obj;
3151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          return original.cellSet().remove(immutableCell(
3161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert              cell.getColumnKey(), cell.getRowKey(), cell.getValue()));
3171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        }
3181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        return false;
3191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
3201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
3211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
3221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
3231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /**
3241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * Creates a table that uses the specified backing map and factory. It can
3251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * generate a table based on arbitrary {@link Map} classes.
3261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
3271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * <p>The {@code factory}-generated and {@code backingMap} classes determine
3281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * the table iteration order. However, the table's {@code row()} method
3291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * returns instances of a different class than {@code factory.get()} does.
3301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
3311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * <p>Call this method only when the simpler factory methods in classes like
3321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * {@link HashBasedTable} and {@link TreeBasedTable} won't suffice.
3331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
3341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * <p>The views returned by the {@code Table} methods {@link Table#column},
3351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * {@link Table#columnKeySet}, and {@link Table#columnMap} have iterators that
3361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * don't support {@code remove()}. Otherwise, all optional operations are
3371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * supported. Null row keys, columns keys, and values are not supported.
3381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
3391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * <p>Lookups by row key are often faster than lookups by column key, because
3401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * the data is stored in a {@code Map<R, Map<C, V>>}. A method call like
3411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * {@code column(columnKey).get(rowKey)} still runs quickly, since the row key
3421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * is provided. However, {@code column(columnKey).size()} takes longer, since
3431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * an iteration across all row keys occurs.
3441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
3451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * <p>Note that this implementation is not synchronized. If multiple threads
3461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * access this table concurrently and one of the threads modifies the table,
3471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * it must be synchronized externally.
3481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
3491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * <p>The table is serializable if {@code backingMap}, {@code factory}, the
3501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * maps generated by {@code factory}, and the table contents are all
3511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * serializable.
3521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
3531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * <p>Note: the table assumes complete ownership over of {@code backingMap}
3541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * and the maps returned by {@code factory}. Those objects should not be
3551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * manually updated and they should not use soft, weak, or phantom references.
3561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
3571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * @param backingMap place to store the mapping from each row key to its
3581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *     corresponding column key / value map
3591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * @param factory supplier of new, empty maps that will each hold all column
3601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *     key / value mappings for a given row key
3611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * @throws IllegalArgumentException if {@code backingMap} is not empty
3621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * @since 10.0
3631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   */
3641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public static <R, C, V> Table<R, C, V> newCustomTable(
3651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      Map<R, Map<C, V>> backingMap, Supplier<? extends Map<C, V>> factory) {
3661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    checkArgument(backingMap.isEmpty());
3671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    checkNotNull(factory);
3681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    // TODO(jlevy): Wrap factory to validate that the supplied maps are empty?
3691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    return new StandardTable<R, C, V>(backingMap, factory);
3701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
3711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
3721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /**
3731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * Returns a view of a table where each value is transformed by a function.
3741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * All other properties of the table, such as iteration order, are left
3751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * intact.
3761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
3771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * <p>Changes in the underlying table are reflected in this view. Conversely,
3781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * this view supports removal operations, and these are reflected in the
3791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * underlying table.
3801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
3811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * <p>It's acceptable for the underlying table to contain null keys, and even
3821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * null values provided that the function is capable of accepting null input.
3831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * The transformed table might contain null values, if the function sometimes
3841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * gives a null result.
3851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
3861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * <p>The returned table is not thread-safe or serializable, even if the
3871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * underlying table is.
3881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
3891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * <p>The function is applied lazily, invoked when needed. This is necessary
3901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * for the returned table to be a view, but it means that the function will be
3911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * applied many times for bulk operations like {@link Table#containsValue} and
3921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * {@code Table.toString()}. For this to perform well, {@code function} should
3931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * be fast. To avoid lazy evaluation when the returned table doesn't need to
3941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * be a view, copy the returned table into a new table of your choosing.
3951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
3961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * @since 10.0
3971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   */
3981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public static <R, C, V1, V2> Table<R, C, V2> transformValues(
3991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      Table<R, C, V1> fromTable, Function<? super V1, V2> function) {
4001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    return new TransformedTable<R, C, V1, V2>(fromTable, function);
4011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
4021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
4031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  private static class TransformedTable<R, C, V1, V2>
4041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      implements Table<R, C, V2> {
4051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    final Table<R, C, V1> fromTable;
4061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    final Function<? super V1, V2> function;
4071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
4081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    TransformedTable(
4091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        Table<R, C, V1> fromTable, Function<? super V1, V2> function) {
4101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      this.fromTable = checkNotNull(fromTable);
4111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      this.function = checkNotNull(function);
4121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
4131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
4141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public boolean contains(Object rowKey, Object columnKey) {
4151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return fromTable.contains(rowKey, columnKey);
4161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
4171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
4181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public boolean containsRow(Object rowKey) {
4191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return fromTable.containsRow(rowKey);
4201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
4211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
4221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public boolean containsColumn(Object columnKey) {
4231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return fromTable.containsColumn(columnKey);
4241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
4251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
4261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public boolean containsValue(Object value) {
4271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return values().contains(value);
4281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
4291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
4301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public V2 get(Object rowKey, Object columnKey) {
4311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      // The function is passed a null input only when the table contains a null
4321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      // value.
4331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return contains(rowKey, columnKey)
4341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          ? function.apply(fromTable.get(rowKey, columnKey)) : null;
4351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
4361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
4371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public boolean isEmpty() {
4381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return fromTable.isEmpty();
4391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
4401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
4411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public int size() {
4421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return fromTable.size();
4431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
4441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
4451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public void clear() {
4461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      fromTable.clear();
4471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
4481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
4491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public V2 put(R rowKey, C columnKey, V2 value) {
4501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      throw new UnsupportedOperationException();
4511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
4521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
4531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public void putAll(
4541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        Table<? extends R, ? extends C, ? extends V2> table) {
4551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      throw new UnsupportedOperationException();
4561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
4571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
4581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public V2 remove(Object rowKey, Object columnKey) {
4591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return contains(rowKey, columnKey)
4601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          ? function.apply(fromTable.remove(rowKey, columnKey)) : null;
4611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
4621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
4631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public Map<C, V2> row(R rowKey) {
4641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return Maps.transformValues(fromTable.row(rowKey), function);
4651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
4661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
4671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public Map<R, V2> column(C columnKey) {
4681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return Maps.transformValues(fromTable.column(columnKey), function);
4691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
4701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
4711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Function<Cell<R, C, V1>, Cell<R, C, V2>> cellFunction() {
4721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return new Function<Cell<R, C, V1>, Cell<R, C, V2>>() {
4731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        @Override public Cell<R, C, V2> apply(Cell<R, C, V1> cell) {
4741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          return immutableCell(
4751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert              cell.getRowKey(), cell.getColumnKey(),
4761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert              function.apply(cell.getValue()));
4771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        }
4781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      };
4791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
4801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
4811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    class CellSet extends TransformedCollection<Cell<R, C, V1>, Cell<R, C, V2>>
4821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        implements Set<Cell<R, C, V2>> {
4831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      CellSet() {
4841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        super(fromTable.cellSet(), cellFunction());
4851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
4861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      @Override public boolean equals(Object obj) {
4871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        return Sets.equalsImpl(this, obj);
4881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
4891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      @Override public int hashCode() {
4901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        return Sets.hashCodeImpl(this);
4911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
4921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      @Override public boolean contains(Object obj) {
4931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        if (obj instanceof Cell) {
4941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          Cell<?, ?, ?> cell = (Cell<?, ?, ?>) obj;
4951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          if (!Objects.equal(
4961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert              cell.getValue(), get(cell.getRowKey(), cell.getColumnKey()))) {
4971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert            return false;
4981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          }
4991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          return cell.getValue() != null
5001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert              || fromTable.contains(cell.getRowKey(), cell.getColumnKey());
5011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        }
5021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        return false;
5031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
5041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      @Override public boolean remove(Object obj) {
5051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        if (contains(obj)) {
5061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          Cell<?, ?, ?> cell = (Cell<?, ?, ?>) obj;
5071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          fromTable.remove(cell.getRowKey(), cell.getColumnKey());
5081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          return true;
5091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        }
5101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        return false;
5111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
5121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
5131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
5141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    CellSet cellSet;
5151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
5161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public Set<Cell<R, C, V2>> cellSet() {
5171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return (cellSet == null) ? cellSet = new CellSet() : cellSet;
5181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
5191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
5201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public Set<R> rowKeySet() {
5211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return fromTable.rowKeySet();
5221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
5231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
5241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public Set<C> columnKeySet() {
5251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return fromTable.columnKeySet();
5261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
5271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
5281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Collection<V2> values;
5291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
5301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public Collection<V2> values() {
5311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return (values == null)
5321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          ? values = Collections2.transform(fromTable.values(), function)
5331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          : values;
5341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
5351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
5361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Map<R, Map<C, V2>> createRowMap() {
5371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      Function<Map<C, V1>, Map<C, V2>> rowFunction =
5381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          new Function<Map<C, V1>, Map<C, V2>>() {
5391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert            @Override public Map<C, V2> apply(Map<C, V1> row) {
5401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert              return Maps.transformValues(row, function);
5411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert            }
5421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          };
5431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return Maps.transformValues(fromTable.rowMap(), rowFunction);
5441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
5451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
5461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Map<R, Map<C, V2>> rowMap;
5471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
5481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public Map<R, Map<C, V2>> rowMap() {
5491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return (rowMap == null) ? rowMap = createRowMap() : rowMap;
5501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
5511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
5521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Map<C, Map<R, V2>> createColumnMap() {
5531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      Function<Map<R, V1>, Map<R, V2>> columnFunction =
5541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          new Function<Map<R, V1>, Map<R, V2>>() {
5551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert            @Override public Map<R, V2> apply(Map<R, V1> column) {
5561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert              return Maps.transformValues(column, function);
5571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert            }
5581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          };
5591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return Maps.transformValues(fromTable.columnMap(), columnFunction);
5601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
5611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
5621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Map<C, Map<R, V2>> columnMap;
5631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
5641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public Map<C, Map<R, V2>> columnMap() {
5651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return (columnMap == null) ? columnMap = createColumnMap() : columnMap;
5661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
5671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
5681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public boolean equals(@Nullable Object obj) {
5691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      if (obj == this) {
5701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        return true;
5711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
5721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      if (obj instanceof Table) {
5731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        Table<?, ?, ?> other = (Table<?, ?, ?>) obj;
5741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        return cellSet().equals(other.cellSet());
5751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
5761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return false;
5771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
5781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
5791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public int hashCode() {
5801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return cellSet().hashCode();
5811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
5821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
5831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public String toString() {
5841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return rowMap().toString();
5851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
5861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
5871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
5881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /**
5891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * Returns an unmodifiable view of the specified table. This method allows modules to provide
5901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * users with "read-only" access to internal tables. Query operations on the returned table
5911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * "read through" to the specified table, and attempts to modify the returned table, whether
5921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * direct or via its collection views, result in an {@code UnsupportedOperationException}.
5931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
5941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * <p>The returned table will be serializable if the specified table is serializable.
5951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
5961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * <p>Consider using an {@link ImmutableTable}, which is guaranteed never to change.
5971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
5981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * @param table
5991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *          the table for which an unmodifiable view is to be returned
6001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * @return an unmodifiable view of the specified table
6011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * @since 11.0
6021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   */
6031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public static <R, C, V> Table<R, C, V> unmodifiableTable(
6041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      Table<? extends R, ? extends C, ? extends V> table) {
6051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    return new UnmodifiableTable<R, C, V>(table);
6061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
6071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
6081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  private static class UnmodifiableTable<R, C, V>
6091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      extends ForwardingTable<R, C, V> implements Serializable {
6101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    final Table<? extends R, ? extends C, ? extends V> delegate;
6111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
6121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    UnmodifiableTable(Table<? extends R, ? extends C, ? extends V> delegate) {
6131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      this.delegate = checkNotNull(delegate);
6141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
6151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
6161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @SuppressWarnings("unchecked") // safe, covariant cast
6171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override
6181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    protected Table<R, C, V> delegate() {
6191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return (Table<R, C, V>) delegate;
6201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
6211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
6221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override
6231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    public Set<Cell<R, C, V>> cellSet() {
6241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return Collections.unmodifiableSet(super.cellSet());
6251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
6261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
6271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override
6281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    public void clear() {
6291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      throw new UnsupportedOperationException();
6301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
6311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
6321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override
6331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    public Map<R, V> column(@Nullable C columnKey) {
6341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return Collections.unmodifiableMap(super.column(columnKey));
6351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
6361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
6371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override
6381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    public Set<C> columnKeySet() {
6391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return Collections.unmodifiableSet(super.columnKeySet());
6401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
6411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
6421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override
6431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    public Map<C, Map<R, V>> columnMap() {
6441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      Function<Map<R, V>, Map<R, V>> wrapper = unmodifiableWrapper();
6451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return Collections.unmodifiableMap(Maps.transformValues(super.columnMap(), wrapper));
6461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
6471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
6481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override
6491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    public V put(@Nullable R rowKey, @Nullable C columnKey, @Nullable V value) {
6501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      throw new UnsupportedOperationException();
6511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
6521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
6531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override
6541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    public void putAll(Table<? extends R, ? extends C, ? extends V> table) {
6551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      throw new UnsupportedOperationException();
6561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
6571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
6581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override
6591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    public V remove(@Nullable Object rowKey, @Nullable Object columnKey) {
6601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      throw new UnsupportedOperationException();
6611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
6621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
6631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override
6641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    public Map<C, V> row(@Nullable R rowKey) {
6651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return Collections.unmodifiableMap(super.row(rowKey));
6661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
6671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
6681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override
6691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    public Set<R> rowKeySet() {
6701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return Collections.unmodifiableSet(super.rowKeySet());
6711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
6721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
6731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override
6741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    public Map<R, Map<C, V>> rowMap() {
6751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      Function<Map<C, V>, Map<C, V>> wrapper = unmodifiableWrapper();
6761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return Collections.unmodifiableMap(Maps.transformValues(super.rowMap(), wrapper));
6771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
6781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
6791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override
6801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    public Collection<V> values() {
6811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return Collections.unmodifiableCollection(super.values());
6821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
6831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
6841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    private static final long serialVersionUID = 0;
6851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
6861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
6871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /**
6881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * Returns an unmodifiable view of the specified row-sorted table. This method allows modules to
6891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * provide users with "read-only" access to internal tables. Query operations on the returned
6901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * table "read through" to the specified table, and attemps to modify the returned table, whether
6911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * direct or via its collection views, result in an {@code UnsupportedOperationException}.
6921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
6931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * <p>The returned table will be serializable if the specified table is serializable.
6941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
6951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * @param table the row-sorted table for which an unmodifiable view is to be returned
6961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * @return an unmodifiable view of the specified table
6971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * @since 11.0
6981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   */
6991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public static <R, C, V> RowSortedTable<R, C, V> unmodifiableRowSortedTable(
7001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      RowSortedTable<R, ? extends C, ? extends V> table) {
7011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    /*
7021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert     * It's not ? extends R, because it's technically not covariant in R. Specifically,
7031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert     * table.rowMap().comparator() could return a comparator that only works for the ? extends R.
7041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert     * Collections.unmodifiableSortedMap makes the same distinction.
7051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert     */
7061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    return new UnmodifiableRowSortedMap<R, C, V>(table);
7071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
7081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
7091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  static final class UnmodifiableRowSortedMap<R, C, V> extends UnmodifiableTable<R, C, V>
7101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      implements RowSortedTable<R, C, V> {
7111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
7121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    public UnmodifiableRowSortedMap(RowSortedTable<R, ? extends C, ? extends V> delegate) {
7131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      super(delegate);
7141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
7151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
7161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override
7171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    protected RowSortedTable<R, C, V> delegate() {
7181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return (RowSortedTable<R, C, V>) super.delegate();
7191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
7201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
7211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override
7221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    public SortedMap<R, Map<C, V>> rowMap() {
7231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      Function<Map<C, V>, Map<C, V>> wrapper = unmodifiableWrapper();
7241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return Collections.unmodifiableSortedMap(Maps.transformValues(delegate().rowMap(), wrapper));
7251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
7261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
7271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override
7281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    public SortedSet<R> rowKeySet() {
7291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return Collections.unmodifiableSortedSet(delegate().rowKeySet());
7301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
7311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
7321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    private static final long serialVersionUID = 0;
7331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
7341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
7351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  @SuppressWarnings("unchecked")
7361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  private static <K, V> Function<Map<K, V>, Map<K, V>> unmodifiableWrapper() {
7371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    return (Function) UNMODIFIABLE_WRAPPER;
7381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
7391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
7401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  private static final Function<? extends Map<?, ?>, ? extends Map<?, ?>> UNMODIFIABLE_WRAPPER =
7411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      new Function<Map<Object, Object>, Map<Object, Object>>() {
7421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        @Override
7431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        public Map<Object, Object> apply(Map<Object, Object> input) {
7441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          return Collections.unmodifiableMap(input);
7451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        }
7461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      };
7471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert}
748