Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  /*
   * Copyright (C) 2008 The Guava Authors
   *
   * Licensed under the Apache License, Version 2.0 (the "License");
   * you may not use this file except in compliance with the License.
   * You may obtain a copy of the License at
   *
   * http://www.apache.org/licenses/LICENSE-2.0
   *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
 
 package com.google.common.collect;
 
 import static com.google.common.base.Preconditions.checkArgument;
 import static com.google.common.base.Preconditions.checkNotNull;
 
 
 import java.util.Map;
 import java.util.Set;
 
Provides static methods that involve a Table.

See the Guava User Guide article on Tables.

Author(s):
Jared Levy
Louis Wasserman
Since:
7.0
 
 public final class Tables {
   private Tables() {}

  
Returns an immutable cell with the specified row key, column key, and value.

The returned cell is serializable.

Parameters:
rowKey the row key to be associated with the returned cell
columnKey the column key to be associated with the returned cell
value the value to be associated with the returned cell
 
   public static <R, C, V> Cell<R, C, V> immutableCell(
       @Nullable R rowKey, @Nullable C columnKey, @Nullable V value) {
     return new ImmutableCell<R, C, V>(rowKeycolumnKeyvalue);
   }
 
   static final class ImmutableCell<R, C, V>
       extends AbstractCell<R, C, V> implements Serializable {
     private final R rowKey;
     private final C columnKey;
     private final V value;
 
     ImmutableCell(
         @Nullable R rowKey, @Nullable C columnKey, @Nullable V value) {
       this. = rowKey;
       this. = columnKey;
       this. = value;
     }
 
     @Override
     public R getRowKey() {
       return ;
     }
     @Override
     public C getColumnKey() {
       return ;
     }
     @Override
     public V getValue() {
       return ;
     }
 
     private static final long serialVersionUID = 0;
   }
 
   abstract static class AbstractCell<R, C, V> implements Cell<R, C, V> {
    // needed for serialization
    AbstractCell() {}
    @Override public boolean equals(Object obj) {
      if (obj == this) {
        return true;
      }
      if (obj instanceof Cell) {
        Cell<?, ?, ?> other = (Cell<?, ?, ?>) obj;
        return Objects.equal(getRowKey(), other.getRowKey())
            && Objects.equal(getColumnKey(), other.getColumnKey())
            && Objects.equal(getValue(), other.getValue());
      }
      return false;
    }
    @Override public int hashCode() {
      return Objects.hashCode(getRowKey(), getColumnKey(), getValue());
    }
    @Override public String toString() {
      return "(" + getRowKey() + "," + getColumnKey() + ")=" + getValue();
    }
  }

  
Creates a transposed view of a given table that flips its row and column keys. In other words, calling get(columnKey, rowKey) on the generated table always returns the same value as calling get(rowKey, columnKey) on the original table. Updating the original table changes the contents of the transposed table and vice versa.

The returned table supports update operations as long as the input table supports the analogous operation with swapped rows and columns. For example, in a HashBasedTable instance, rowKeySet().iterator() supports remove() but columnKeySet().iterator() doesn't. With a transposed HashBasedTable, it's the other way around.

  public static <R, C, V> Table<C, R, V> transpose(Table<R, C, V> table) {
    return (table instanceof TransposeTable)
        ? ((TransposeTable<R, C, V>) table).
        : new TransposeTable<C, R, V>(table);
  }
  private static class TransposeTable<C, R, V> extends AbstractTable<C, R, V> {
    final Table<R, C, V> original;
    TransposeTable(Table<R, C, V> original) {
      this. = checkNotNull(original);
    }
    @Override
    public void clear() {
      .clear();
    }
    @Override
    public Map<C, V> column(R columnKey) {
      return .row(columnKey);
    }
    @Override
    public Set<R> columnKeySet() {
      return .rowKeySet();
    }
    @Override
    public Map<R, Map<C, V>> columnMap() {
      return .rowMap();
    }
    @Override
    public boolean contains(
        @Nullable Object rowKey, @Nullable Object columnKey) {
      return .contains(columnKeyrowKey);
    }
    @Override
    public boolean containsColumn(@Nullable Object columnKey) {
      return .containsRow(columnKey);
    }
    @Override
    public boolean containsRow(@Nullable Object rowKey) {
      return .containsColumn(rowKey);
    }
    @Override
    public boolean containsValue(@Nullable Object value) {
      return .containsValue(value);
    }
    @Override
    public V get(@Nullable Object rowKey, @Nullable Object columnKey) {
      return .get(columnKeyrowKey);
    }
    @Override
    public V put(C rowKey, R columnKey, V value) {
      return .put(columnKeyrowKeyvalue);
    }
    @Override
    public void putAll(Table<? extends C, ? extends R, ? extends V> table) {
      .putAll(transpose(table));
    }
    @Override
    public V remove(@Nullable Object rowKey, @Nullable Object columnKey) {
      return .remove(columnKeyrowKey);
    }
    @Override
    public Map<R, V> row(C rowKey) {
      return .column(rowKey);
    }
    @Override
    public Set<C> rowKeySet() {
      return .columnKeySet();
    }
    @Override
    public Map<C, Map<R, V>> rowMap() {
      return .columnMap();
    }
    @Override
    public int size() {
      return .size();
    }
    @Override
    public Collection<V> values() {
      return .values();
    }
    // Will cast TRANSPOSE_CELL to a type that always succeeds
    private static final Function<Cell<?, ?, ?>, Cell<?, ?, ?>> TRANSPOSE_CELL =
        new Function<Cell<?, ?, ?>, Cell<?, ?, ?>>() {
          @Override
          public Cell<?, ?, ?> apply(Cell<?, ?, ?> cell) {
            return immutableCell(
                cell.getColumnKey(), cell.getRowKey(), cell.getValue());
          }
        };
    @SuppressWarnings("unchecked")
    @Override
    Iterator<Cell<C, R, V>> cellIterator() {
      return Iterators.transform(.cellSet().iterator(), (Function);
    }
  }

  
Creates a table that uses the specified backing map and factory. It can generate a table based on arbitrary java.util.Map classes.

The factory-generated and backingMap classes determine the table iteration order. However, the table's row() method returns instances of a different class than factory.get() does.

Call this method only when the simpler factory methods in classes like HashBasedTable and TreeBasedTable won't suffice.

The views returned by the Table methods Table.column(java.lang.Object), Table.columnKeySet(), and Table.columnMap() have iterators that don't support remove(). Otherwise, all optional operations are supported. Null row keys, columns keys, and values are not supported.

Lookups by row key are often faster than lookups by column key, because the data is stored in a Map<R, Map<C, V>>. A method call like column(columnKey).get(rowKey) still runs quickly, since the row key is provided. However, column(columnKey).size() takes longer, since an iteration across all row keys occurs.

Note that this implementation is not synchronized. If multiple threads access this table concurrently and one of the threads modifies the table, it must be synchronized externally.

The table is serializable if backingMap, factory, the maps generated by factory, and the table contents are all serializable.

Note: the table assumes complete ownership over of backingMap and the maps returned by factory. Those objects should not be manually updated and they should not use soft, weak, or phantom references.

Parameters:
backingMap place to store the mapping from each row key to its corresponding column key / value map
factory supplier of new, empty maps that will each hold all column key / value mappings for a given row key
Throws:
java.lang.IllegalArgumentException if backingMap is not empty
Since:
10.0
  @Beta
  public static <R, C, V> Table<R, C, V> newCustomTable(
      Map<R, Map<C, V>> backingMapSupplier<? extends Map<C, V>> factory) {
    checkArgument(backingMap.isEmpty());
    checkNotNull(factory);
    // TODO(jlevy): Wrap factory to validate that the supplied maps are empty?
    return new StandardTable<R, C, V>(backingMapfactory);
  }

  
Returns a view of a table where each value is transformed by a function. All other properties of the table, such as iteration order, are left intact.

Changes in the underlying table are reflected in this view. Conversely, this view supports removal operations, and these are reflected in the underlying table.

It's acceptable for the underlying table to contain null keys, and even null values provided that the function is capable of accepting null input. The transformed table might contain null values, if the function sometimes gives a null result.

The returned table is not thread-safe or serializable, even if the underlying table is.

The function is applied lazily, invoked when needed. This is necessary for the returned table to be a view, but it means that the function will be applied many times for bulk operations like Table.containsValue(java.lang.Object) and Table.toString(). For this to perform well, function should be fast. To avoid lazy evaluation when the returned table doesn't need to be a view, copy the returned table into a new table of your choosing.

Since:
10.0
  @Beta
  public static <R, C, V1, V2> Table<R, C, V2> transformValues(
      Table<R, C, V1> fromTableFunction<? super V1, V2> function) {
    return new TransformedTable<R, C, V1, V2>(fromTablefunction);
  }
  private static class TransformedTable<R, C, V1, V2>
      extends AbstractTable<R, C, V2> {
    final Table<R, C, V1> fromTable;
    final Function<? super V1, V2> function;
        Table<R, C, V1> fromTableFunction<? super V1, V2> function) {
      this. = checkNotNull(fromTable);
      this. = checkNotNull(function);
    }
    @Override public boolean contains(Object rowKeyObject columnKey) {
      return .contains(rowKeycolumnKey);
    }
    @Override public V2 get(Object rowKeyObject columnKey) {
      // The function is passed a null input only when the table contains a null
      // value.
      return contains(rowKeycolumnKey)
          ? .apply(.get(rowKeycolumnKey)) : null;
    }
    @Override public int size() {
      return .size();
    }
    @Override public void clear() {
      .clear();
    }
    @Override public V2 put(R rowKey, C columnKey, V2 value) {
      throw new UnsupportedOperationException();
    }
    @Override public void putAll(
        Table<? extends R, ? extends C, ? extends V2> table) {
      throw new UnsupportedOperationException();
    }
    @Override public V2 remove(Object rowKeyObject columnKey) {
      return contains(rowKeycolumnKey)
          ? .apply(.remove(rowKeycolumnKey)) : null;
    }
    @Override public Map<C, V2> row(R rowKey) {
      return Maps.transformValues(.row(rowKey), );
    }
    @Override public Map<R, V2> column(C columnKey) {
      return Maps.transformValues(.column(columnKey), );
    }
    Function<Cell<R, C, V1>, Cell<R, C, V2>> cellFunction() {
      return new Function<Cell<R, C, V1>, Cell<R, C, V2>>() {
        @Override public Cell<R, C, V2> apply(Cell<R, C, V1> cell) {
          return immutableCell(
              cell.getRowKey(), cell.getColumnKey(),
              .apply(cell.getValue()));
        }
      };
    }
    @Override
    Iterator<Cell<R, C, V2>> cellIterator() {
      return Iterators.transform(.cellSet().iterator(), cellFunction());
    }
    @Override public Set<R> rowKeySet() {
      return .rowKeySet();
    }
    @Override public Set<C> columnKeySet() {
      return .columnKeySet();
    }
    @Override
    Collection<V2> createValues() {
      return Collections2.transform(.values(), );
    }
    @Override public Map<R, Map<C, V2>> rowMap() {
      Function<Map<C, V1>, Map<C, V2>> rowFunction =
          new Function<Map<C, V1>, Map<C, V2>>() {
            @Override public Map<C, V2> apply(Map<C, V1> row) {
              return Maps.transformValues(row);
            }
          };
      return Maps.transformValues(.rowMap(), rowFunction);
    }
    @Override public Map<C, Map<R, V2>> columnMap() {
      Function<Map<R, V1>, Map<R, V2>> columnFunction =
          new Function<Map<R, V1>, Map<R, V2>>() {
            @Override public Map<R, V2> apply(Map<R, V1> column) {
              return Maps.transformValues(column);
            }
          };
      return Maps.transformValues(.columnMap(), columnFunction);
    }
  }
  
  
Returns an unmodifiable view of the specified table. This method allows modules to provide users with "read-only" access to internal tables. Query operations on the returned table "read through" to the specified table, and attempts to modify the returned table, whether direct or via its collection views, result in an UnsupportedOperationException.

The returned table will be serializable if the specified table is serializable.

Consider using an ImmutableTable, which is guaranteed never to change.

Parameters:
table the table for which an unmodifiable view is to be returned
Returns:
an unmodifiable view of the specified table
Since:
11.0
  public static <R, C, V> Table<R, C, V> unmodifiableTable(
      Table<? extends R, ? extends C, ? extends V> table) {
    return new UnmodifiableTable<R, C, V>(table);
  }
  
  private static class UnmodifiableTable<R, C, V>
      extends ForwardingTable<R, C, V> implements Serializable {
    final Table<? extends R, ? extends C, ? extends V> delegate;
    UnmodifiableTable(Table<? extends R, ? extends C, ? extends V> delegate) {
      this. = checkNotNull(delegate);
    }
    @SuppressWarnings("unchecked"// safe, covariant cast
    @Override
    protected Table<R, C, V> delegate() {
      return (Table<R, C, V>) ;
    }
    @Override
    public Set<Cell<R, C, V>> cellSet() {
      return Collections.unmodifiableSet(super.cellSet());
    }
    @Override
    public void clear() {
      throw new UnsupportedOperationException();
    }
    @Override
    public Map<R, V> column(@Nullable C columnKey) {
      return Collections.unmodifiableMap(super.column(columnKey));
    }
    @Override
    public Set<C> columnKeySet() {
      return Collections.unmodifiableSet(super.columnKeySet());
    }
    @Override
    public Map<C, Map<R, V>> columnMap() {
      Function<Map<R, V>, Map<R, V>> wrapper = unmodifiableWrapper();
      return Collections.unmodifiableMap(Maps.transformValues(super.columnMap(), wrapper));
    }
    @Override
    public V put(@Nullable R rowKey, @Nullable C columnKey, @Nullable V value) {
      throw new UnsupportedOperationException();
    }
    @Override
    public void putAll(Table<? extends R, ? extends C, ? extends V> table) {
      throw new UnsupportedOperationException();
    }
    @Override
    public V remove(@Nullable Object rowKey, @Nullable Object columnKey) {
      throw new UnsupportedOperationException();
    }
    @Override
    public Map<C, V> row(@Nullable R rowKey) {
      return Collections.unmodifiableMap(super.row(rowKey));
    }
    @Override
    public Set<R> rowKeySet() {
      return Collections.unmodifiableSet(super.rowKeySet());
    }
    @Override
    public Map<R, Map<C, V>> rowMap() {
      Function<Map<C, V>, Map<C, V>> wrapper = unmodifiableWrapper();
      return Collections.unmodifiableMap(Maps.transformValues(super.rowMap(), wrapper));
    }
    @Override
    public Collection<V> values() {
      return Collections.unmodifiableCollection(super.values());
    }
    
    private static final long serialVersionUID = 0;
  }

  
Returns an unmodifiable view of the specified row-sorted table. This method allows modules to provide users with "read-only" access to internal tables. Query operations on the returned table "read through" to the specified table, and attemps to modify the returned table, whether direct or via its collection views, result in an UnsupportedOperationException.

The returned table will be serializable if the specified table is serializable.

Parameters:
table the row-sorted table for which an unmodifiable view is to be returned
Returns:
an unmodifiable view of the specified table
Since:
11.0
  @Beta
  public static <R, C, V> RowSortedTable<R, C, V> unmodifiableRowSortedTable(
      RowSortedTable<R, ? extends C, ? extends V> table) {
    /*
     * It's not ? extends R, because it's technically not covariant in R. Specifically,
     * table.rowMap().comparator() could return a comparator that only works for the ? extends R.
     * Collections.unmodifiableSortedMap makes the same distinction.
     */
    return new UnmodifiableRowSortedMap<R, C, V>(table);
  }
  
  static final class UnmodifiableRowSortedMap<R, C, V> extends UnmodifiableTable<R, C, V>
      implements RowSortedTable<R, C, V> {
    public UnmodifiableRowSortedMap(RowSortedTable<R, ? extends C, ? extends V> delegate) {
      super(delegate);
    }
    @Override
    protected RowSortedTable<R, C, V> delegate() {
      return (RowSortedTable<R, C, V>) super.delegate();
    }
    @Override
    public SortedMap<R, Map<C, V>> rowMap() {
      Function<Map<C, V>, Map<C, V>> wrapper = unmodifiableWrapper();
      return Collections.unmodifiableSortedMap(Maps.transformValues(delegate().rowMap(), wrapper));
    }
    @Override
    public SortedSet<R> rowKeySet() {
      return Collections.unmodifiableSortedSet(delegate().rowKeySet());
    }
    private static final long serialVersionUID = 0;
  }
  @SuppressWarnings("unchecked")
  private static <K, V> Function<Map<K, V>, Map<K, V>> unmodifiableWrapper() {
    return (Function;
  }
  private static final Function<? extends Map<?, ?>, ? extends Map<?, ?>> UNMODIFIABLE_WRAPPER =
      new Function<Map<ObjectObject>, Map<ObjectObject>>() {
        @Override
        public Map<ObjectObjectapply(Map<ObjectObjectinput) {
          return Collections.unmodifiableMap(input);
        }
      };
      
  static boolean equalsImpl(Table<?, ?, ?> table, @Nullable Object obj) {
    if (obj == table) {
      return true;
    } else if (obj instanceof Table) {
      Table<?, ?, ?> that = (Table<?, ?, ?>) obj;
      return table.cellSet().equals(that.cellSet());
    } else {
      return false;
    }
  }
New to GrepCode? Check out our FAQ X