11d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert/*
21d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Copyright (C) 2009 Google Inc.
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.checkNotNull;
201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.annotations.Beta;
221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.annotations.GwtCompatible;
231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.Comparator;
251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.List;
261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.Map;
271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport javax.annotation.Nullable;
291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert/**
311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * An immutable {@link Table} with reliable user-specified iteration order.
321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Does not permit null keys or values.
331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *
341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p><b>Note</b>: Although this class is not final, it cannot be subclassed as
351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * it has no public or protected constructors. Thus, instances of this class are
361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * guaranteed to be immutable.
371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *
381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @author gak@google.com (Gregory Kick)
391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @since 11.0
401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */
411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert@Beta
421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert@GwtCompatible
431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert// TODO(gak): make serializable
441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertpublic abstract class ImmutableTable<R, C, V> implements Table<R, C, V> {
451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /** Returns an empty immutable table. */
461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  @SuppressWarnings("unchecked")
471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public static final <R, C, V> ImmutableTable<R, C, V> of() {
481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    return (ImmutableTable<R, C, V>) EmptyImmutableTable.INSTANCE;
491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /** Returns an immutable table containing a single cell. */
521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public static final <R, C, V> ImmutableTable<R, C, V> of(R rowKey,
531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      C columnKey, V value) {
541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    return new SingletonImmutableTable<R, C, V>(rowKey, columnKey, value);
551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /**
581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * Returns an immutable copy of the provided table.
591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * <p>The {@link Table#cellSet()} iteration order of the provided table
611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * determines the iteration ordering of all views in the returned table. Note
621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * that some views of the original table and the copied table may have
631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * different iteration orders. For more control over the ordering, create a
641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * {@link Builder} and call {@link Builder#orderRowsBy},
651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * {@link Builder#orderColumnsBy}, and {@link Builder#putAll}
661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * <p>Despite the method name, this method attempts to avoid actually copying
681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * the data when it is safe to do so. The exact circumstances under which a
691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * copy will or will not be performed are undocumented and subject to change.
701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   */
711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public static final <R, C, V> ImmutableTable<R, C, V> copyOf(
721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      Table<? extends R, ? extends C, ? extends V> table) {
731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    if (table instanceof ImmutableTable<?, ?, ?>) {
741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      @SuppressWarnings("unchecked")
751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      ImmutableTable<R, C, V> parameterizedTable
761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          = (ImmutableTable<R, C, V>) table;
771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return parameterizedTable;
781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    } else {
791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      int size = table.size();
801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      switch (size) {
811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        case 0:
821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          return of();
831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        case 1:
841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          Cell<? extends R, ? extends C, ? extends V> onlyCell
851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert              = Iterables.getOnlyElement(table.cellSet());
861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          return ImmutableTable.<R, C, V>of(onlyCell.getRowKey(),
871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert              onlyCell.getColumnKey(), onlyCell.getValue());
881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        default:
891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          ImmutableSet.Builder<Cell<R, C, V>> cellSetBuilder
901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert              = ImmutableSet.builder();
911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          for (Cell<? extends R, ? extends C, ? extends V> cell :
921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert              table.cellSet()) {
931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert            /*
941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert             * Must cast to be able to create a Cell<R, C, V> rather than a
951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert             * Cell<? extends R, ? extends C, ? extends V>
961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert             */
971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert            cellSetBuilder.add(cellOf((R) cell.getRowKey(),
981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert                (C) cell.getColumnKey(), (V) cell.getValue()));
991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          }
1001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          return RegularImmutableTable.forCells(cellSetBuilder.build());
1011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
1021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
1031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
1041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /**
1061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * Returns a new builder. The generated builder is equivalent to the builder
1071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * created by the {@link Builder#Builder()} constructor.
1081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   */
1091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public static final <R, C, V> Builder<R, C, V> builder() {
1101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    return new Builder<R, C, V>();
1111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
1121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /**
1141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * Verifies that {@code rowKey}, {@code columnKey} and {@code value} are
1151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * non-null, and returns a new entry with those values.
1161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   */
1171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  static <R, C, V> Cell<R, C, V> cellOf(R rowKey, C columnKey, V value) {
1181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    return Tables.immutableCell(checkNotNull(rowKey), checkNotNull(columnKey),
1191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        checkNotNull(value));
1201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
1211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /**
1231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * A builder for creating immutable table instances, especially {@code public
1241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * static final} tables ("constant tables"). Example: <pre>   {@code
1251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
1261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *   static final ImmutableTable<Integer, Character, String> SPREADSHEET =
1271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *       new ImmutableTable.Builder<Integer, Character, String>()
1281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *           .put(1, 'A', "foo")
1291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *           .put(1, 'B', "bar")
1301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *           .put(2, 'A', "baz")
1311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *           .build();}</pre>
1321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
1331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * <p>By default, the order in which cells are added to the builder determines
1341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * the iteration ordering of all views in the returned table, with {@link
1351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * #putAll} following the {@link Table#cellSet()} iteration order. However, if
1361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * {@link #orderRowsBy} or {@link #orderColumnsBy} is called, the views are
1371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * sorted by the supplied comparators.
1381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
1391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * For empty or single-cell immutable tables, {@link #of()} and
1401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * {@link #of(Object, Object, Object)} are even more convenient.
1411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
1421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * <p>Builder instances can be reused - it is safe to call {@link #build}
1431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * multiple times to build multiple tables in series. Each table is a superset
1441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * of the tables created before it.
1451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
1461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * @since 11.0
1471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   */
1481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public static final class Builder<R, C, V> {
1491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    private final List<Cell<R, C, V>> cells = Lists.newArrayList();
1501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    private Comparator<? super R> rowComparator;
1511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    private Comparator<? super C> columnComparator;
1521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    /**
1541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert     * Creates a new builder. The returned builder is equivalent to the builder
1551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert     * generated by {@link ImmutableTable#builder}.
1561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert     */
1571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    public Builder() {}
1581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    /**
1601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert     * Specifies the ordering of the generated table's rows.
1611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert     */
1621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    public Builder<R, C, V> orderRowsBy(Comparator<? super R> rowComparator) {
1631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      this.rowComparator = checkNotNull(rowComparator);
1641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return this;
1651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
1661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    /**
1681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert     * Specifies the ordering of the generated table's columns.
1691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert     */
1701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    public Builder<R, C, V> orderColumnsBy(
1711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        Comparator<? super C> columnComparator) {
1721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      this.columnComparator = checkNotNull(columnComparator);
1731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return this;
1741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
1751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    /**
1771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert     * Associates the ({@code rowKey}, {@code columnKey}) pair with {@code
1781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert     * value} in the built table. Duplicate key pairs are not allowed and will
1791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert     * cause {@link #build} to fail.
1801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert     */
1811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    public Builder<R, C, V> put(R rowKey, C columnKey, V value) {
1821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      cells.add(cellOf(rowKey, columnKey, value));
1831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return this;
1841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
1851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    /**
1871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert     * Adds the given {@code cell} to the table, making it immutable if
1881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert     * necessary. Duplicate key pairs are not allowed and will cause {@link
1891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert     * #build} to fail.
1901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert     */
1911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    public Builder<R, C, V> put(
1921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        Cell<? extends R, ? extends C, ? extends V> cell) {
1931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      if (cell instanceof Tables.ImmutableCell) {
1941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        checkNotNull(cell.getRowKey());
1951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        checkNotNull(cell.getColumnKey());
1961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        checkNotNull(cell.getValue());
1971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        @SuppressWarnings("unchecked") // all supported methods are covariant
1981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        Cell<R, C, V> immutableCell = (Cell<R, C, V>) cell;
1991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        cells.add(immutableCell);
2001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      } else {
2011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        put(cell.getRowKey(), cell.getColumnKey(), cell.getValue());
2021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
2031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return this;
2041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
2051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    /**
2071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert     * Associates all of the given table's keys and values in the built table.
2081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert     * Duplicate row key column key pairs are not allowed, and will cause
2091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert     * {@link #build} to fail.
2101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert     *
2111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert     * @throws NullPointerException if any key or value in {@code table} is null
2121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert     */
2131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    public Builder<R, C, V> putAll(
2141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        Table<? extends R, ? extends C, ? extends V> table) {
2151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      for (Cell<? extends R, ? extends C, ? extends V> cell : table.cellSet()) {
2161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        put(cell);
2171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
2181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return this;
2191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
2201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    /**
2221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert     * Returns a newly-created immutable table.
2231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert     *
2241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert     * @throws IllegalArgumentException if duplicate key pairs were added
2251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert     */
2261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    public ImmutableTable<R, C, V> build() {
2271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      int size = cells.size();
2281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      switch (size) {
2291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        case 0:
2301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          return of();
2311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        case 1:
2321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          return new SingletonImmutableTable<R, C, V>(
2331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert              Iterables.getOnlyElement(cells));
2341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        default:
2351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert         return RegularImmutableTable.forCells(
2361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert             cells, rowComparator, columnComparator);
2371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
2381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
2391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
2401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  ImmutableTable() {}
2421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  @Override public abstract ImmutableSet<Cell<R, C, V>> cellSet();
2441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /**
2461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * {@inheritDoc}
2471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
2481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * @throws NullPointerException if {@code columnKey} is {@code null}
2491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   */
2501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  @Override public abstract ImmutableMap<R, V> column(C columnKey);
2511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  @Override public abstract ImmutableSet<C> columnKeySet();
2531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /**
2551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * {@inheritDoc}
2561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
2571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * <p>The value {@code Map<R, V>}s in the returned map are
2581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * {@link ImmutableMap}s as well.
2591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   */
2601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  @Override public abstract ImmutableMap<C, Map<R, V>> columnMap();
2611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /**
2631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * {@inheritDoc}
2641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
2651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * @throws NullPointerException if {@code rowKey} is {@code null}
2661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   */
2671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  @Override public abstract ImmutableMap<C, V> row(R rowKey);
2681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  @Override public abstract ImmutableSet<R> rowKeySet();
2701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /**
2721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * {@inheritDoc}
2731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
2741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * <p>The value {@code Map<C, V>}s in the returned map are
2751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * {@link ImmutableMap}s as well.
2761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   */
2771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  @Override public abstract ImmutableMap<R, Map<C, V>> rowMap();
2781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /**
2801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * Guaranteed to throw an exception and leave the table unmodified.
2811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
2821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * @throws UnsupportedOperationException always
2831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   */
2841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  @Override public final void clear() {
2851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    throw new UnsupportedOperationException();
2861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
2871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /**
2891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * Guaranteed to throw an exception and leave the table unmodified.
2901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
2911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * @throws UnsupportedOperationException always
2921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   */
2931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  @Override public final V put(R rowKey, C columnKey, V value) {
2941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    throw new UnsupportedOperationException();
2951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
2961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /**
2981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * Guaranteed to throw an exception and leave the table unmodified.
2991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
3001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * @throws UnsupportedOperationException always
3011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   */
3021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  @Override public final void putAll(
3031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      Table<? extends R, ? extends C, ? extends V> table) {
3041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    throw new UnsupportedOperationException();
3051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
3061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
3071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /**
3081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * Guaranteed to throw an exception and leave the table unmodified.
3091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
3101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * @throws UnsupportedOperationException always
3111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   */
3121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  @Override public final V remove(Object rowKey, Object columnKey) {
3131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    throw new UnsupportedOperationException();
3141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
3151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
3161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  @Override public boolean equals(@Nullable Object obj) {
3171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    if (obj == this) {
3181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return true;
3191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    } else if (obj instanceof Table<?, ?, ?>) {
3201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      Table<?, ?, ?> that = (Table<?, ?, ?>) obj;
3211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return this.cellSet().equals(that.cellSet());
3221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    } else {
3231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return false;
3241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
3251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
3261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
3271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  @Override public int hashCode() {
3281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    return cellSet().hashCode();
3291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
3301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
3311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  @Override public String toString() {
3321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    return rowMap().toString();
3331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
3341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert}
335