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 * <p>See the Guava User Guide article on <a href=
049 * "https://github.com/google/guava/wiki/NewCollectionTypesExplained#table">{@code Table}</a>.
050 *
051 * @author Jared Levy
052 * @param <R> the type of the table row keys
053 * @param <C> the type of the table column keys
054 * @param <V> the type of the mapped values
055 * @since 7.0
056 */
057@DoNotMock("Use ImmutableTable, HashBasedTable, or another implementation")
058@GwtCompatible
059@ElementTypesAreNonnullByDefault
060public interface Table<
061    R extends @Nullable Object, C extends @Nullable Object, V extends @Nullable Object> {
062  // TODO(jlevy): Consider adding methods similar to ConcurrentMap methods.
063
064  // Accessors
065
066  /**
067   * Returns {@code true} if the table contains a mapping with the specified row and column keys.
068   *
069   * @param rowKey key of row to search for
070   * @param columnKey key of column to search for
071   */
072  boolean contains(
073      @CompatibleWith("R") @CheckForNull Object rowKey,
074      @CompatibleWith("C") @CheckForNull Object columnKey);
075
076  /**
077   * Returns {@code true} if the table contains a mapping with the specified row key.
078   *
079   * @param rowKey key of row to search for
080   */
081  boolean containsRow(@CompatibleWith("R") @CheckForNull Object rowKey);
082
083  /**
084   * Returns {@code true} if the table contains a mapping with the specified column.
085   *
086   * @param columnKey key of column to search for
087   */
088  boolean containsColumn(@CompatibleWith("C") @CheckForNull Object columnKey);
089
090  /**
091   * Returns {@code true} if the table contains a mapping with the specified value.
092   *
093   * @param value value to search for
094   */
095  boolean containsValue(@CompatibleWith("V") @CheckForNull Object value);
096
097  /**
098   * Returns the value corresponding to the given row and column keys, or {@code null} if no such
099   * mapping exists.
100   *
101   * @param rowKey key of row to search for
102   * @param columnKey key of column to search for
103   */
104  @CheckForNull
105  V get(
106      @CompatibleWith("R") @CheckForNull Object rowKey,
107      @CompatibleWith("C") @CheckForNull Object columnKey);
108
109  /** Returns {@code true} if the table contains no mappings. */
110  boolean isEmpty();
111
112  /** Returns the number of row key / column key / value mappings in the table. */
113  int size();
114
115  /**
116   * Compares the specified object with this table for equality. Two tables are equal when their
117   * cell views, as returned by {@link #cellSet}, are equal.
118   */
119  @Override
120  boolean equals(@CheckForNull Object obj);
121
122  /**
123   * Returns the hash code for this table. The hash code of a table is defined as the hash code of
124   * its cell view, as returned by {@link #cellSet}.
125   */
126  @Override
127  int hashCode();
128
129  // Mutators
130
131  /** Removes all mappings from the table. */
132  void clear();
133
134  /**
135   * Associates the specified value with the specified keys. If the table already contained a
136   * mapping for those keys, the old value is replaced with the specified value.
137   *
138   * @param rowKey row key that the value should be associated with
139   * @param columnKey column key that the value should be associated with
140   * @param value value to be associated with the specified keys
141   * @return the value previously associated with the keys, or {@code null} if no mapping existed
142   *     for the keys
143   */
144  @CanIgnoreReturnValue
145  @CheckForNull
146  V put(@ParametricNullness R rowKey, @ParametricNullness C columnKey, @ParametricNullness V value);
147
148  /**
149   * Copies all mappings from the specified table to this table. The effect is equivalent to calling
150   * {@link #put} with each row key / column key / value mapping in {@code table}.
151   *
152   * @param table the table to add to this table
153   */
154  void putAll(Table<? extends R, ? extends C, ? extends V> table);
155
156  /**
157   * Removes the mapping, if any, associated with the given keys.
158   *
159   * @param rowKey row key of mapping to be removed
160   * @param columnKey column key of mapping to be removed
161   * @return the value previously associated with the keys, or {@code null} if no such value existed
162   */
163  @CanIgnoreReturnValue
164  @CheckForNull
165  V remove(
166      @CompatibleWith("R") @CheckForNull Object rowKey,
167      @CompatibleWith("C") @CheckForNull Object columnKey);
168
169  // Views
170
171  /**
172   * Returns a view of all mappings that have the given row key. For each row key / column key /
173   * value mapping in the table with that row key, the returned map associates the column key with
174   * the value. If no mappings in the table have the provided row key, an empty map is returned.
175   *
176   * <p>Changes to the returned map will update the underlying table, and vice versa.
177   *
178   * @param rowKey key of row to search for in the table
179   * @return the corresponding map from column keys to values
180   */
181  Map<C, V> row(@ParametricNullness R rowKey);
182
183  /**
184   * Returns a view of all mappings that have the given column key. For each row key / column key /
185   * value mapping in the table with that column key, the returned map associates the row key with
186   * the value. If no mappings in the table have the provided column key, an empty map is returned.
187   *
188   * <p>Changes to the returned map will update the underlying table, and vice versa.
189   *
190   * @param columnKey key of column to search for in the table
191   * @return the corresponding map from row keys to values
192   */
193  Map<R, V> column(@ParametricNullness C columnKey);
194
195  /**
196   * Returns a set of all row key / column key / value triplets. Changes to the returned set will
197   * update the underlying table, and vice versa. The cell set does not support the {@code add} or
198   * {@code addAll} methods.
199   *
200   * @return set of table cells consisting of row key / column key / value triplets
201   */
202  Set<Cell<R, C, V>> cellSet();
203
204  /**
205   * Returns a set of row keys that have one or more values in the table. Changes to the set will
206   * update the underlying table, and vice versa.
207   *
208   * @return set of row keys
209   */
210  Set<R> rowKeySet();
211
212  /**
213   * Returns a set of column keys that have one or more values in the table. Changes to the set will
214   * update the underlying table, and vice versa.
215   *
216   * @return set of column keys
217   */
218  Set<C> columnKeySet();
219
220  /**
221   * Returns a collection of all values, which may contain duplicates. Changes to the returned
222   * collection will update the underlying table, and vice versa.
223   *
224   * @return collection of values
225   */
226  Collection<V> values();
227
228  /**
229   * Returns a view that associates each row key with the corresponding map from column keys to
230   * values. Changes to the returned map will update this table. The returned map does not support
231   * {@code put()} or {@code putAll()}, or {@code setValue()} on its entries.
232   *
233   * <p>In contrast, the maps returned by {@code rowMap().get()} have the same behavior as those
234   * returned by {@link #row}. Those maps may support {@code setValue()}, {@code put()}, and {@code
235   * putAll()}.
236   *
237   * @return a map view from each row key to a secondary map from column keys to values
238   */
239  Map<R, Map<C, V>> rowMap();
240
241  /**
242   * Returns a view that associates each column key with the corresponding map from row keys to
243   * values. Changes to the returned map will update this table. The returned map does not support
244   * {@code put()} or {@code putAll()}, or {@code setValue()} on its entries.
245   *
246   * <p>In contrast, the maps returned by {@code columnMap().get()} have the same behavior as those
247   * returned by {@link #column}. Those maps may support {@code setValue()}, {@code put()}, and
248   * {@code putAll()}.
249   *
250   * @return a map view from each column key to a secondary map from row keys to values
251   */
252  Map<C, Map<R, V>> columnMap();
253
254  /**
255   * Row key / column key / value triplet corresponding to a mapping in a table.
256   *
257   * @since 7.0
258   */
259  interface Cell<
260      R extends @Nullable Object, C extends @Nullable Object, V extends @Nullable Object> {
261    /** Returns the row key of this cell. */
262    @ParametricNullness
263    R getRowKey();
264
265    /** Returns the column key of this cell. */
266    @ParametricNullness
267    C getColumnKey();
268
269    /** Returns the value of this cell. */
270    @ParametricNullness
271    V getValue();
272
273    /**
274     * Compares the specified object with this cell for equality. Two cells are equal when they have
275     * equal row keys, column keys, and values.
276     */
277    @Override
278    boolean equals(@CheckForNull Object obj);
279
280    /**
281     * Returns the hash code of this cell.
282     *
283     * <p>The hash code of a table cell is equal to {@link Objects#hashCode}{@code (e.getRowKey(),
284     * e.getColumnKey(), e.getValue())}.
285     */
286    @Override
287    int hashCode();
288  }
289}