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