001/*
002 * Copyright (C) 2008 The Guava Authors
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016
017package com.google.common.collect;
018
019import com.google.common.annotations.GwtCompatible;
020import com.google.common.base.Objects;
021import com.google.errorprone.annotations.CanIgnoreReturnValue;
022import com.google.errorprone.annotations.CompatibleWith;
023import com.google.errorprone.annotations.DoNotMock;
024import java.util.Collection;
025import java.util.Map;
026import java.util.Set;
027import javax.annotation.CheckForNull;
028import org.checkerframework.checker.nullness.qual.Nullable;
029
030/**
031 * A collection that associates an ordered pair of keys, called a row key and a column key, with a
032 * single value. A table may be sparse, with only a small fraction of row key / column key pairs
033 * possessing a corresponding value.
034 *
035 * <p>The mappings corresponding to a given row key may be viewed as a {@link Map} whose keys are
036 * the columns. The reverse is also available, associating a column with a row key / value map. Note
037 * that, in some implementations, data access by column key may have fewer supported operations or
038 * worse performance than data access by row key.
039 *
040 * <p>The methods returning collections or maps always return views of the underlying table.
041 * Updating the table can change the contents of those collections, and updating the collections
042 * will change the table.
043 *
044 * <p>All methods that modify the table are optional, and the views returned by the table may or may
045 * not be modifiable. When modification isn't supported, those methods will throw an {@link
046 * UnsupportedOperationException}.
047 *
048 * <h3>Implementations</h3>
049 *
050 * <ul>
051 *   <li>{@link ImmutableTable}
052 *   <li>{@link HashBasedTable}
053 *   <li>{@link TreeBasedTable}
054 *   <li>{@link ArrayTable}
055 *   <li>{@link Tables#newCustomTable Tables.newCustomTable}
056 * </ul>
057 *
058 * <p>See the Guava User Guide article on <a href=
059 * "https://github.com/google/guava/wiki/NewCollectionTypesExplained#table">{@code Table}</a>.
060 *
061 * @author Jared Levy
062 * @param <R> the type of the table row keys
063 * @param <C> the type of the table column keys
064 * @param <V> the type of the mapped values
065 * @since 7.0
066 */
067@DoNotMock("Use ImmutableTable, HashBasedTable, or another implementation")
068@GwtCompatible
069public interface Table<
070    R extends @Nullable Object, C extends @Nullable Object, V extends @Nullable Object> {
071  // TODO(jlevy): Consider adding methods similar to ConcurrentMap methods.
072
073  // Accessors
074
075  /**
076   * Returns {@code true} if the table contains a mapping with the specified row and column keys.
077   *
078   * @param rowKey key of row to search for
079   * @param columnKey key of column to search for
080   */
081  boolean contains(
082      @CompatibleWith("R") @CheckForNull Object rowKey,
083      @CompatibleWith("C") @CheckForNull Object columnKey);
084
085  /**
086   * Returns {@code true} if the table contains a mapping with the specified row key.
087   *
088   * @param rowKey key of row to search for
089   */
090  boolean containsRow(@CompatibleWith("R") @CheckForNull Object rowKey);
091
092  /**
093   * Returns {@code true} if the table contains a mapping with the specified column.
094   *
095   * @param columnKey key of column to search for
096   */
097  boolean containsColumn(@CompatibleWith("C") @CheckForNull Object columnKey);
098
099  /**
100   * Returns {@code true} if the table contains a mapping with the specified value.
101   *
102   * @param value value to search for
103   */
104  boolean containsValue(@CompatibleWith("V") @CheckForNull Object value);
105
106  /**
107   * Returns the value corresponding to the given row and column keys, or {@code null} if no such
108   * mapping exists.
109   *
110   * @param rowKey key of row to search for
111   * @param columnKey key of column to search for
112   */
113  @CheckForNull
114  V get(
115      @CompatibleWith("R") @CheckForNull Object rowKey,
116      @CompatibleWith("C") @CheckForNull Object columnKey);
117
118  /** Returns {@code true} if the table contains no mappings. */
119  boolean isEmpty();
120
121  /** Returns the number of row key / column key / value mappings in the table. */
122  int size();
123
124  /**
125   * Compares the specified object with this table for equality. Two tables are equal when their
126   * cell views, as returned by {@link #cellSet}, are equal.
127   */
128  @Override
129  boolean equals(@CheckForNull Object obj);
130
131  /**
132   * Returns the hash code for this table. The hash code of a table is defined as the hash code of
133   * its cell view, as returned by {@link #cellSet}.
134   */
135  @Override
136  int hashCode();
137
138  // Mutators
139
140  /** Removes all mappings from the table. */
141  void clear();
142
143  /**
144   * Associates the specified value with the specified keys. If the table already contained a
145   * mapping for those keys, the old value is replaced with the specified value.
146   *
147   * @param rowKey row key that the value should be associated with
148   * @param columnKey column key that the value should be associated with
149   * @param value value to be associated with the specified keys
150   * @return the value previously associated with the keys, or {@code null} if no mapping existed
151   *     for the keys
152   */
153  @CanIgnoreReturnValue
154  @CheckForNull
155  V put(@ParametricNullness R rowKey, @ParametricNullness C columnKey, @ParametricNullness V value);
156
157  /**
158   * Copies all mappings from the specified table to this table. The effect is equivalent to calling
159   * {@link #put} with each row key / column key / value mapping in {@code table}.
160   *
161   * @param table the table to add to this table
162   */
163  void putAll(Table<? extends R, ? extends C, ? extends V> table);
164
165  /**
166   * Removes the mapping, if any, associated with the given keys.
167   *
168   * @param rowKey row key of mapping to be removed
169   * @param columnKey column key of mapping to be removed
170   * @return the value previously associated with the keys, or {@code null} if no such value existed
171   */
172  @CanIgnoreReturnValue
173  @CheckForNull
174  V remove(
175      @CompatibleWith("R") @CheckForNull Object rowKey,
176      @CompatibleWith("C") @CheckForNull Object columnKey);
177
178  // Views
179
180  /**
181   * Returns a view of all mappings that have the given row key. For each row key / column key /
182   * value mapping in the table with that row key, the returned map associates the column key with
183   * the value. If no mappings in the table have the provided row key, an empty map is returned.
184   *
185   * <p>Changes to the returned map will update the underlying table, and vice versa.
186   *
187   * @param rowKey key of row to search for in the table
188   * @return the corresponding map from column keys to values
189   */
190  Map<C, V> row(@ParametricNullness R rowKey);
191
192  /**
193   * Returns a view of all mappings that have the given column key. For each row key / column key /
194   * value mapping in the table with that column key, the returned map associates the row key with
195   * the value. If no mappings in the table have the provided column key, an empty map is returned.
196   *
197   * <p>Changes to the returned map will update the underlying table, and vice versa.
198   *
199   * @param columnKey key of column to search for in the table
200   * @return the corresponding map from row keys to values
201   */
202  Map<R, V> column(@ParametricNullness C columnKey);
203
204  /**
205   * Returns a set of all row key / column key / value triplets. Changes to the returned set will
206   * update the underlying table, and vice versa. The cell set does not support the {@code add} or
207   * {@code addAll} methods.
208   *
209   * @return set of table cells consisting of row key / column key / value triplets
210   */
211  Set<Cell<R, C, V>> cellSet();
212
213  /**
214   * Returns a set of row keys that have one or more values in the table. Changes to the set will
215   * update the underlying table, and vice versa.
216   *
217   * @return set of row keys
218   */
219  Set<R> rowKeySet();
220
221  /**
222   * Returns a set of column keys that have one or more values in the table. Changes to the set will
223   * update the underlying table, and vice versa.
224   *
225   * @return set of column keys
226   */
227  Set<C> columnKeySet();
228
229  /**
230   * Returns a collection of all values, which may contain duplicates. Changes to the returned
231   * collection will update the underlying table, and vice versa.
232   *
233   * @return collection of values
234   */
235  Collection<V> values();
236
237  /**
238   * Returns a view that associates each row key with the corresponding map from column keys to
239   * values. Changes to the returned map will update this table. The returned map does not support
240   * {@code put()} or {@code putAll()}, or {@code setValue()} on its entries.
241   *
242   * <p>In contrast, the maps returned by {@code rowMap().get()} have the same behavior as those
243   * returned by {@link #row}. Those maps may support {@code setValue()}, {@code put()}, and {@code
244   * putAll()}.
245   *
246   * @return a map view from each row key to a secondary map from column keys to values
247   */
248  Map<R, Map<C, V>> rowMap();
249
250  /**
251   * Returns a view that associates each column key with the corresponding map from row keys to
252   * values. Changes to the returned map will update this table. The returned map does not support
253   * {@code put()} or {@code putAll()}, or {@code setValue()} on its entries.
254   *
255   * <p>In contrast, the maps returned by {@code columnMap().get()} have the same behavior as those
256   * returned by {@link #column}. Those maps may support {@code setValue()}, {@code put()}, and
257   * {@code putAll()}.
258   *
259   * @return a map view from each column key to a secondary map from row keys to values
260   */
261  Map<C, Map<R, V>> columnMap();
262
263  /**
264   * Row key / column key / value triplet corresponding to a mapping in a table.
265   *
266   * @since 7.0
267   */
268  interface Cell<
269      R extends @Nullable Object, C extends @Nullable Object, V extends @Nullable Object> {
270    /** Returns the row key of this cell. */
271    @ParametricNullness
272    R getRowKey();
273
274    /** Returns the column key of this cell. */
275    @ParametricNullness
276    C getColumnKey();
277
278    /** Returns the value of this cell. */
279    @ParametricNullness
280    V getValue();
281
282    /**
283     * Compares the specified object with this cell for equality. Two cells are equal when they have
284     * equal row keys, column keys, and values.
285     */
286    @Override
287    boolean equals(@CheckForNull Object obj);
288
289    /**
290     * Returns the hash code of this cell.
291     *
292     * <p>The hash code of a table cell is equal to {@link Objects#hashCode}{@code (e.getRowKey(),
293     * e.getColumnKey(), e.getValue())}.
294     */
295    @Override
296    int hashCode();
297  }
298}