11d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert/* 21d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Copyright (C) 2009 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.base.Objects; 241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.io.Serializable; 261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.lang.reflect.Array; 271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.AbstractCollection; 281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.AbstractMap; 291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.AbstractSet; 301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.Arrays; 311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.Collection; 321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.Iterator; 331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.Map; 341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.Map.Entry; 351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.Set; 361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport javax.annotation.Nullable; 381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert/** 401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Fixed-size {@link Table} implementation backed by a two-dimensional array. 411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>The allowed row and column keys must be supplied when the table is 431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * created. The table always contains a mapping for every row key / column pair. 441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * The value corresponding to a given row and column is null unless another 451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * value is provided. 461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>The table's size is constant: the product of the number of supplied row 481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * keys and the number of supplied column keys. The {@code remove} and {@code 491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * clear} methods are not supported by the table or its views. The {@link 501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * #erase} and {@link #eraseAll} methods may be used instead. 511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>The ordering of the row and column keys provided when the table is 531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * constructed determines the iteration ordering across rows and columns in the 541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * table's views. None of the view iterators support {@link Iterator#remove}. 551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * If the table is modified after an iterator is created, the iterator remains 561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * valid. 571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>This class requires less memory than the {@link HashBasedTable} and {@link 591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * TreeBasedTable} implementations, except when the table is sparse. 601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>Null row keys or column keys are not permitted. 621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>This class provides methods involving the underlying array structure, 641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * where the array indices correspond to the position of a row or column in the 651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * lists of allowed keys and values. See the {@link #at}, {@link #set}, {@link 661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * #toArray}, {@link #rowKeyList}, and {@link #columnKeyList} methods for more 671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * details. 681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>Note that this implementation is not synchronized. If multiple threads 701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * access the same cell of an {@code ArrayTable} concurrently and one of the 711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * threads modifies its value, there is no guarantee that the new value will be 721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * fully visible to the other threads. To guarantee that modifications are 731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * visible, synchronize access to the table. Unlike other {@code Table} 741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * implementations, synchronization is unnecessary between a thread that writes 751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * to one cell and a thread that reads from another. 761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @author Jared Levy 781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @since 10.0 791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert@Beta 811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertpublic final class ArrayTable<R, C, V> implements Table<R, C, V>, Serializable { 821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Creates an empty {@code ArrayTable}. 851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @param rowKeys row keys that may be stored in the generated table 871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @param columnKeys column keys that may be stored in the generated table 881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @throws NullPointerException if any of the provided keys is null 891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @throws IllegalArgumentException if {@code rowKeys} or {@code columnKeys} 901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * contains duplicates or is empty 911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public static <R, C, V> ArrayTable<R, C, V> create( 931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Iterable<? extends R> rowKeys, Iterable<? extends C> columnKeys) { 941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return new ArrayTable<R, C, V>(rowKeys, columnKeys); 951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /* 981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * TODO(jlevy): Add factory methods taking an Enum class, instead of an 991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * iterable, to specify the allowed row keys and/or column keys. Note that 1001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * custom serialization logic is needed to support different enum sizes during 1011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * serialization and deserialization. 1021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 1031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 1051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Creates an {@code ArrayTable} with the mappings in the provided table. 1061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 1071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>If {@code table} includes a mapping with row key {@code r} and a 1081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * separate mapping with column key {@code c}, the returned table contains a 1091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * mapping with row key {@code r} and column key {@code c}. If that row key / 1101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * column key pair in not in {@code table}, the pair maps to {@code null} in 1111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * the generated table. 1121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 1131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>The returned table allows subsequent {@code put} calls with the row keys 1141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * in {@code table.rowKeySet()} and the column keys in {@code 1151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * table.columnKeySet()}. Calling {@link #put} with other keys leads to an 1161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@code IllegalArgumentException}. 1171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 1181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>The ordering of {@code table.rowKeySet()} and {@code 1191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * table.columnKeySet()} determines the row and column iteration ordering of 1201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * the returned table. 1211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 1221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @throws NullPointerException if {@code table} has a null key 1231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @throws IllegalArgumentException if the provided table is empty 1241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 1251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public static <R, C, V> ArrayTable<R, C, V> create(Table<R, C, V> table) { 1261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return new ArrayTable<R, C, V>(table); 1271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 1301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Creates an {@code ArrayTable} with the same mappings, allowed keys, and 1311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * iteration ordering as the provided {@code ArrayTable}. 1321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 1331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public static <R, C, V> ArrayTable<R, C, V> create( 1341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert ArrayTable<R, C, V> table) { 1351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return new ArrayTable<R, C, V>(table); 1361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private final ImmutableList<R> rowList; 1391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private final ImmutableList<C> columnList; 1401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // TODO(jlevy): Add getters returning rowKeyToIndex and columnKeyToIndex? 1421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private final ImmutableMap<R, Integer> rowKeyToIndex; 1431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private final ImmutableMap<C, Integer> columnKeyToIndex; 1441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private final V[][] array; 1451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private ArrayTable(Iterable<? extends R> rowKeys, 1471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Iterable<? extends C> columnKeys) { 1481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert this.rowList = ImmutableList.copyOf(rowKeys); 1491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert this.columnList = ImmutableList.copyOf(columnKeys); 1501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkArgument(!rowList.isEmpty()); 1511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkArgument(!columnList.isEmpty()); 1521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /* 1541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * TODO(jlevy): Support empty rowKeys or columnKeys? If we do, when 1551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * columnKeys is empty but rowKeys isn't, the table is empty but 1561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * containsRow() can return true and rowKeySet() isn't empty. 1571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 1581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert ImmutableMap.Builder<R, Integer> rowBuilder = ImmutableMap.builder(); 1591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert for (int i = 0; i < rowList.size(); i++) { 1601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert rowBuilder.put(rowList.get(i), i); 1611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert rowKeyToIndex = rowBuilder.build(); 1631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert ImmutableMap.Builder<C, Integer> columnBuilder = ImmutableMap.builder(); 1651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert for (int i = 0; i < columnList.size(); i++) { 1661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert columnBuilder.put(columnList.get(i), i); 1671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert columnKeyToIndex = columnBuilder.build(); 1691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @SuppressWarnings("unchecked") 1711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert V[][] tmpArray 1721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert = (V[][]) new Object[rowList.size()][columnList.size()]; 1731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert array = tmpArray; 1741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private ArrayTable(Table<R, C, V> table) { 1771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert this(table.rowKeySet(), table.columnKeySet()); 1781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert putAll(table); 1791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private ArrayTable(ArrayTable<R, C, V> table) { 1821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert rowList = table.rowList; 1831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert columnList = table.columnList; 1841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert rowKeyToIndex = table.rowKeyToIndex; 1851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert columnKeyToIndex = table.columnKeyToIndex; 1861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @SuppressWarnings("unchecked") 1871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert V[][] copy = (V[][]) new Object[rowList.size()][columnList.size()]; 1881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert array = copy; 1891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert for (int i = 0; i < rowList.size(); i++) { 1901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert System.arraycopy(table.array[i], 0, copy[i], 0, table.array[i].length); 1911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 1951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Returns, as an immutable list, the row keys provided when the table was 1961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * constructed, including those that are mapped to null values only. 1971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 1981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public ImmutableList<R> rowKeyList() { 1991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return rowList; 2001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 2011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 2021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 2031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Returns, as an immutable list, the column keys provided when the table was 2041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * constructed, including those that are mapped to null values only. 2051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 2061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public ImmutableList<C> columnKeyList() { 2071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return columnList; 2081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 2091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 2101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 2111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Returns the value corresponding to the specified row and column indices. 2121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * The same value is returned by {@code 2131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * get(rowKeyList().get(rowIndex), columnKeyList().get(columnIndex))}, but 2141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * this method runs more quickly. 2151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 2161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @param rowIndex position of the row key in {@link #rowKeyList()} 2171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @param columnIndex position of the row key in {@link #columnKeyList()} 2181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @return the value with the specified row and column 2191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @throws IndexOutOfBoundsException if either index is negative, {@code 2201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * rowIndex} is greater then or equal to the number of allowed row keys, 2211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * or {@code columnIndex} is greater then or equal to the number of 2221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * allowed column keys 2231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 2241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public V at(int rowIndex, int columnIndex) { 2251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return array[rowIndex][columnIndex]; 2261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 2271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 2281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 2291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Associates {@code value} with the specified row and column indices. The 2301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * logic {@code 2311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * put(rowKeyList().get(rowIndex), columnKeyList().get(columnIndex), value)} 2321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * has the same behavior, but this method runs more quickly. 2331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 2341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @param rowIndex position of the row key in {@link #rowKeyList()} 2351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @param columnIndex position of the row key in {@link #columnKeyList()} 2361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @param value value to store in the table 2371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @return the previous value with the specified row and column 2381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @throws IndexOutOfBoundsException if either index is negative, {@code 2391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * rowIndex} is greater then or equal to the number of allowed row keys, 2401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * or {@code columnIndex} is greater then or equal to the number of 2411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * allowed column keys 2421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 2431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public V set(int rowIndex, int columnIndex, @Nullable V value) { 2441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert V oldValue = array[rowIndex][columnIndex]; 2451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert array[rowIndex][columnIndex] = value; 2461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return oldValue; 2471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 2481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 2491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 2501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Returns a two-dimensional array with the table contents. The row and column 2511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * indices correspond to the positions of the row and column in the iterables 2521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * provided during table construction. If the table lacks a mapping for a 2531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * given row and column, the corresponding array element is null. 2541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 2551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>Subsequent table changes will not modify the array, and vice versa. 2561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 2571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @param valueClass class of values stored in the returned array 2581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 2591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public V[][] toArray(Class<V> valueClass) { 2601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // Can change to use varargs in JDK 1.6 if we want 2611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @SuppressWarnings("unchecked") // TODO: safe? 2621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert V[][] copy = (V[][]) Array.newInstance( 2631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert valueClass, new int[] { rowList.size(), columnList.size() }); 2641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert for (int i = 0; i < rowList.size(); i++) { 2651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert System.arraycopy(array[i], 0, copy[i], 0, array[i].length); 2661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 2671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return copy; 2681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 2691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 2701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 2711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Not supported. Use {@link #eraseAll} instead. 2721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 2731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @throws UnsupportedOperationException always 2741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @deprecated Use {@link #eraseAll} 2751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 2761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 2771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Deprecated public void clear() { 2781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert throw new UnsupportedOperationException(); 2791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 2801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 2811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 2821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Associates the value {@code null} with every pair of allowed row and column 2831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * keys. 2841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 2851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void eraseAll() { 2861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert for (V[] row : array) { 2871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Arrays.fill(row, null); 2881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 2891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 2901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 2911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 2921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Returns {@code true} if the provided keys are among the keys provided when 2931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * the table was constructed. 2941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 2951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 2961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public boolean contains(@Nullable Object rowKey, @Nullable Object columnKey) { 2971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return containsRow(rowKey) && containsColumn(columnKey); 2981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 2991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 3001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 3011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Returns {@code true} if the provided column key is among the column keys 3021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * provided when the table was constructed. 3031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 3041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 3051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public boolean containsColumn(@Nullable Object columnKey) { 3061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return columnKeyToIndex.containsKey(columnKey); 3071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 3081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 3091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 3101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Returns {@code true} if the provided row key is among the row keys 3111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * provided when the table was constructed. 3121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 3131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 3141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public boolean containsRow(@Nullable Object rowKey) { 3151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return rowKeyToIndex.containsKey(rowKey); 3161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 3171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 3181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 3191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public boolean containsValue(@Nullable Object value) { 3201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert for (V[] row : array) { 3211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert for (V element : row) { 3221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (Objects.equal(value, element)) { 3231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return true; 3241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 3251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 3261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 3271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return false; 3281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 3291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 3301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 3311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public V get(@Nullable Object rowKey, @Nullable Object columnKey) { 3321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Integer rowIndex = rowKeyToIndex.get(rowKey); 3331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Integer columnIndex = columnKeyToIndex.get(columnKey); 3341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return getIndexed(rowIndex, columnIndex); 3351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 3361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 3371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private V getIndexed(Integer rowIndex, Integer columnIndex) { 3381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return (rowIndex == null || columnIndex == null) 3391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert ? null : array[rowIndex][columnIndex]; 3401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 3411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 3421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 3431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Always returns {@code false}. 3441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 3451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 3461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public boolean isEmpty() { 3471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return false; 3481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 3491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 3501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 3511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@inheritDoc} 3521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 3531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @throws IllegalArgumentException if {@code rowKey} is not in {@link 3541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * #rowKeySet()} or {@code columnKey} is not in {@link #columnKeySet()}. 3551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 3561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 3571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public V put(R rowKey, C columnKey, @Nullable V value) { 3581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkNotNull(rowKey); 3591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkNotNull(columnKey); 3601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Integer rowIndex = rowKeyToIndex.get(rowKey); 3611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkArgument(rowIndex != null, "Row %s not in %s", rowKey, rowList); 3621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Integer columnIndex = columnKeyToIndex.get(columnKey); 3631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkArgument(columnIndex != null, 3641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert "Column %s not in %s", columnKey, columnList); 3651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return set(rowIndex, columnIndex, value); 3661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 3671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 3681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /* 3691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * TODO(jlevy): Consider creating a merge() method, similar to putAll() but 3701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * copying non-null values only. 3711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 3721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 3731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 3741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * {@inheritDoc} 3751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 3761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>If {@code table} is an {@code ArrayTable}, its null values will be 3771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * stored in this table, possibly replacing values that were previously 3781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * non-null. 3791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 3801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @throws NullPointerException if {@code table} has a null key 3811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @throws IllegalArgumentException if any of the provided table's row keys or 3821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * column keys is not in {@link #rowKeySet()} or {@link #columnKeySet()} 3831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 3841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 3851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public void putAll(Table<? extends R, ? extends C, ? extends V> table) { 3861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert for (Cell<? extends R, ? extends C, ? extends V> cell : table.cellSet()) { 3871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert put(cell.getRowKey(), cell.getColumnKey(), cell.getValue()); 3881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 3891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 3901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 3911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 3921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Not supported. Use {@link #erase} instead. 3931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 3941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @throws UnsupportedOperationException always 3951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @deprecated Use {@link #erase} 3961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 3971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 3981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Deprecated public V remove(Object rowKey, Object columnKey) { 3991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert throw new UnsupportedOperationException(); 4001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 4011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 4021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 4031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Associates the value {@code null} with the specified keys, assuming both 4041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * keys are valid. If either key is null or isn't among the keys provided 4051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * during construction, this method has no effect. 4061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 4071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>This method is equivalent to {@code put(rowKey, columnKey, null)} when 4081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * both provided keys are valid. 4091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 4101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @param rowKey row key of mapping to be erased 4111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @param columnKey column key of mapping to be erased 4121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @return the value previously associated with the keys, or {@code null} if 4131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * no mapping existed for the keys 4141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 4151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public V erase(@Nullable Object rowKey, @Nullable Object columnKey) { 4161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Integer rowIndex = rowKeyToIndex.get(rowKey); 4171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Integer columnIndex = columnKeyToIndex.get(columnKey); 4181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (rowIndex == null || columnIndex == null) { 4191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return null; 4201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 4211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return set(rowIndex, columnIndex, null); 4221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 4231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 4241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // TODO(jlevy): Add eraseRow and eraseColumn methods? 4251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 4261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 4271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public int size() { 4281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return rowList.size() * columnList.size(); 4291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 4301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 4311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public boolean equals(@Nullable Object obj) { 4321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (obj instanceof Table) { 4331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Table<?, ?, ?> other = (Table<?, ?, ?>) obj; 4341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return cellSet().equals(other.cellSet()); 4351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 4361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return false; 4371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 4381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 4391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public int hashCode() { 4401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return cellSet().hashCode(); 4411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 4421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 4431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 4441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Returns the string representation {@code rowMap().toString()}. 4451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 4461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public String toString() { 4471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return rowMap().toString(); 4481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 4491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 4501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private transient CellSet cellSet; 4511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 4521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 4531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Returns an unmodifiable set of all row key / column key / value 4541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * triplets. Changes to the table will update the returned set. 4551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 4561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>The returned set's iterator traverses the mappings with the first row 4571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * key, the mappings with the second row key, and so on. 4581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 4591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>The value in the returned cells may change if the table subsequently 4601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * changes. 4611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 4621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @return set of table cells consisting of row key / column key / value 4631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * triplets 4641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 4651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 4661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public Set<Cell<R, C, V>> cellSet() { 4671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert CellSet set = cellSet; 4681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return (set == null) ? cellSet = new CellSet() : set; 4691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 4701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 4711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private class CellSet extends AbstractSet<Cell<R, C, V>> { 4721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 4731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public Iterator<Cell<R, C, V>> iterator() { 4741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return new AbstractIndexedListIterator<Cell<R, C, V>>(size()) { 4751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override protected Cell<R, C, V> get(final int index) { 4761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return new Tables.AbstractCell<R, C, V>() { 4771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert final int rowIndex = index / columnList.size(); 4781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert final int columnIndex = index % columnList.size(); 4791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 4801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public R getRowKey() { 4811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return rowList.get(rowIndex); 4821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 4831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 4841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public C getColumnKey() { 4851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return columnList.get(columnIndex); 4861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 4871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 4881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public V getValue() { 4891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return array[rowIndex][columnIndex]; 4901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 4911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert }; 4921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 4931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert }; 4941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 4951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 4961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public int size() { 4971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return ArrayTable.this.size(); 4981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 4991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 5001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public boolean contains(Object obj) { 5011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (obj instanceof Cell) { 5021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Cell<?, ?, ?> cell = (Cell<?, ?, ?>) obj; 5031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Integer rowIndex = rowKeyToIndex.get(cell.getRowKey()); 5041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Integer columnIndex = columnKeyToIndex.get(cell.getColumnKey()); 5051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return rowIndex != null 5061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert && columnIndex != null 5071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert && Objects.equal(array[rowIndex][columnIndex], cell.getValue()); 5081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 5091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return false; 5101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 5111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 5121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 5131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 5141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Returns a view of all mappings that have the given column key. If the 5151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * column key isn't in {@link #columnKeySet()}, an empty immutable map is 5161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * returned. 5171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 5181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>Otherwise, for each row key in {@link #rowKeySet()}, the returned map 5191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * associates the row key with the corresponding value in the table. Changes 5201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * to the returned map will update the underlying table, and vice versa. 5211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 5221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @param columnKey key of column to search for in the table 5231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @return the corresponding map from row keys to values 5241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 5251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 5261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public Map<R, V> column(C columnKey) { 5271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkNotNull(columnKey); 5281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Integer columnIndex = columnKeyToIndex.get(columnKey); 5291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return (columnIndex == null) 5301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert ? ImmutableMap.<R, V>of() : new Column(columnIndex); 5311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 5321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 5331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private class Column extends AbstractMap<R, V> { 5341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert final int columnIndex; 5351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 5361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Column(int columnIndex) { 5371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert this.columnIndex = columnIndex; 5381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 5391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 5401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert ColumnEntrySet entrySet; 5411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 5421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public Set<Entry<R, V>> entrySet() { 5431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert ColumnEntrySet set = entrySet; 5441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return (set == null) ? entrySet = new ColumnEntrySet(columnIndex) : set; 5451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 5461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 5471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public V get(Object rowKey) { 5481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Integer rowIndex = rowKeyToIndex.get(rowKey); 5491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return getIndexed(rowIndex, columnIndex); 5501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 5511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 5521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public boolean containsKey(Object rowKey) { 5531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return rowKeyToIndex.containsKey(rowKey); 5541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 5551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 5561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public V put(R rowKey, V value) { 5571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkNotNull(rowKey); 5581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Integer rowIndex = rowKeyToIndex.get(rowKey); 5591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkArgument(rowIndex != null, "Row %s not in %s", rowKey, rowList); 5601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return set(rowIndex, columnIndex, value); 5611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 5621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 5631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public Set<R> keySet() { 5641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return rowKeySet(); 5651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 5661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 5671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 5681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private class ColumnEntrySet extends AbstractSet<Entry<R, V>> { 5691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert final int columnIndex; 5701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 5711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert ColumnEntrySet(int columnIndex) { 5721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert this.columnIndex = columnIndex; 5731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 5741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 5751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public Iterator<Entry<R, V>> iterator() { 5761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return new AbstractIndexedListIterator<Entry<R, V>>(size()) { 5771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override protected Entry<R, V> get(final int rowIndex) { 5781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return new AbstractMapEntry<R, V>() { 5791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public R getKey() { 5801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return rowList.get(rowIndex); 5811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 5821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public V getValue() { 5831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return array[rowIndex][columnIndex]; 5841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 5851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public V setValue(V value) { 5861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return ArrayTable.this.set(rowIndex, columnIndex, value); 5871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 5881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert }; 5891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 5901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert }; 5911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 5921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 5931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public int size() { 5941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return rowList.size(); 5951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 5961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 5971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 5981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 5991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Returns an immutable set of the valid column keys, including those that 6001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * are associated with null values only. 6011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 6021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @return immutable set of column keys 6031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 6041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 6051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public ImmutableSet<C> columnKeySet() { 6061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return columnKeyToIndex.keySet(); 6071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 6081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 6091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private transient ColumnMap columnMap; 6101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 6111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 6121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public Map<C, Map<R, V>> columnMap() { 6131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert ColumnMap map = columnMap; 6141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return (map == null) ? columnMap = new ColumnMap() : map; 6151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 6161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 6171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private class ColumnMap extends AbstractMap<C, Map<R, V>> { 6181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert transient ColumnMapEntrySet entrySet; 6191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 6201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public Set<Entry<C, Map<R, V>>> entrySet() { 6211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert ColumnMapEntrySet set = entrySet; 6221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return (set == null) ? entrySet = new ColumnMapEntrySet() : set; 6231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 6241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 6251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public Map<R, V> get(Object columnKey) { 6261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Integer columnIndex = columnKeyToIndex.get(columnKey); 6271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return (columnIndex == null) ? null : new Column(columnIndex); 6281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 6291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 6301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public boolean containsKey(Object columnKey) { 6311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return containsColumn(columnKey); 6321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 6331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 6341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public Set<C> keySet() { 6351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return columnKeySet(); 6361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 6371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 6381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public Map<R, V> remove(Object columnKey) { 6391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert throw new UnsupportedOperationException(); 6401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 6411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 6421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 6431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private class ColumnMapEntrySet extends AbstractSet<Entry<C, Map<R, V>>> { 6441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public Iterator<Entry<C, Map<R, V>>> iterator() { 6451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return new AbstractIndexedListIterator<Entry<C, Map<R, V>>>(size()) { 6461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override protected Entry<C, Map<R, V>> get(int index) { 6471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return Maps.<C, Map<R, V>>immutableEntry(columnList.get(index), 6481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert new Column(index)); 6491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 6501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert }; 6511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 6521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 6531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public int size() { 6541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return columnList.size(); 6551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 6561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 6571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 6581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 6591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Returns a view of all mappings that have the given row key. If the 6601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * row key isn't in {@link #rowKeySet()}, an empty immutable map is 6611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * returned. 6621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 6631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>Otherwise, for each column key in {@link #columnKeySet()}, the returned 6641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * map associates the column key with the corresponding value in the 6651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * table. Changes to the returned map will update the underlying table, and 6661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * vice versa. 6671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 6681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @param rowKey key of row to search for in the table 6691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @return the corresponding map from column keys to values 6701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 6711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 6721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public Map<C, V> row(R rowKey) { 6731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkNotNull(rowKey); 6741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Integer rowIndex = rowKeyToIndex.get(rowKey); 6751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return (rowIndex == null) ? ImmutableMap.<C, V>of() : new Row(rowIndex); 6761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 6771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 6781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private class Row extends AbstractMap<C, V> { 6791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert final int rowIndex; 6801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 6811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Row(int rowIndex) { 6821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert this.rowIndex = rowIndex; 6831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 6841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 6851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert RowEntrySet entrySet; 6861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 6871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public Set<Entry<C, V>> entrySet() { 6881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert RowEntrySet set = entrySet; 6891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return (set == null) ? entrySet = new RowEntrySet(rowIndex) : set; 6901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 6911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 6921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public V get(Object columnKey) { 6931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Integer columnIndex = columnKeyToIndex.get(columnKey); 6941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return getIndexed(rowIndex, columnIndex); 6951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 6961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 6971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public boolean containsKey(Object columnKey) { 6981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return containsColumn(columnKey); 6991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 7001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 7011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public V put(C columnKey, V value) { 7021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkNotNull(columnKey); 7031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Integer columnIndex = columnKeyToIndex.get(columnKey); 7041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert checkArgument(columnIndex != null, 7051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert "Column %s not in %s", columnKey, columnList); 7061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return set(rowIndex, columnIndex, value); 7071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 7081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 7091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public Set<C> keySet() { 7101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return columnKeySet(); 7111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 7121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 7131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 7141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private class RowEntrySet extends AbstractSet<Entry<C, V>> { 7151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert final int rowIndex; 7161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 7171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert RowEntrySet(int rowIndex) { 7181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert this.rowIndex = rowIndex; 7191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 7201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 7211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public Iterator<Entry<C, V>> iterator() { 7221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return new AbstractIndexedListIterator<Entry<C, V>>(size()) { 7231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override protected Entry<C, V> get(final int columnIndex) { 7241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return new AbstractMapEntry<C, V>() { 7251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public C getKey() { 7261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return columnList.get(columnIndex); 7271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 7281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public V getValue() { 7291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return array[rowIndex][columnIndex]; 7301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 7311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public V setValue(V value) { 7321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return ArrayTable.this.set(rowIndex, columnIndex, value); 7331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 7341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert }; 7351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 7361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert }; 7371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 7381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 7391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public int size() { 7401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return columnList.size(); 7411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 7421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 7431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 7441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 7451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Returns an immutable set of the valid row keys, including those that are 7461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * associated with null values only. 7471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 7481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @return immutable set of row keys 7491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 7501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 7511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public ImmutableSet<R> rowKeySet() { 7521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return rowKeyToIndex.keySet(); 7531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 7541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 7551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private transient RowMap rowMap; 7561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 7571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 7581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public Map<R, Map<C, V>> rowMap() { 7591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert RowMap map = rowMap; 7601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return (map == null) ? rowMap = new RowMap() : map; 7611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 7621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 7631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private class RowMap extends AbstractMap<R, Map<C, V>> { 7641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert transient RowMapEntrySet entrySet; 7651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 7661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public Set<Entry<R, Map<C, V>>> entrySet() { 7671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert RowMapEntrySet set = entrySet; 7681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return (set == null) ? entrySet = new RowMapEntrySet() : set; 7691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 7701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 7711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public Map<C, V> get(Object rowKey) { 7721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Integer rowIndex = rowKeyToIndex.get(rowKey); 7731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return (rowIndex == null) ? null : new Row(rowIndex); 7741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 7751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 7761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public boolean containsKey(Object rowKey) { 7771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return containsRow(rowKey); 7781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 7791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 7801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public Set<R> keySet() { 7811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return rowKeySet(); 7821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 7831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 7841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public Map<C, V> remove(Object rowKey) { 7851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert throw new UnsupportedOperationException(); 7861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 7871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 7881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 7891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private class RowMapEntrySet extends AbstractSet<Entry<R, Map<C, V>>> { 7901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public Iterator<Entry<R, Map<C, V>>> iterator() { 7911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return new AbstractIndexedListIterator<Entry<R, Map<C, V>>>(size()) { 7921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override protected Entry<R, Map<C, V>> get(int index) { 7931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return Maps.<R, Map<C, V>>immutableEntry(rowList.get(index), 7941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert new Row(index)); 7951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 7961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert }; 7971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 7981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 7991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public int size() { 8001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return rowList.size(); 8011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 8021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 8031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 8041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private transient Collection<V> values; 8051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 8061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /** 8071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Returns an unmodifiable collection of all values, which may contain 8081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * duplicates. Changes to the table will update the returned collection. 8091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 8101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p>The returned collection's iterator traverses the values of the first row 8111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * key, the values of the second row key, and so on. 8121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 8131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @return collection of values 8141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 8151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 8161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public Collection<V> values() { 8171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Collection<V> v = values; 8181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return (v == null) ? values = new Values() : v; 8191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 8201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 8211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private class Values extends AbstractCollection<V> { 8221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public Iterator<V> iterator() { 8231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return new AbstractIndexedListIterator<V>(size()) { 8241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override protected V get(int index) { 8251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert int rowIndex = index / columnList.size(); 8261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert int columnIndex = index % columnList.size(); 8271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return array[rowIndex][columnIndex]; 8281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 8291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert }; 8301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 8311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 8321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public int size() { 8331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return ArrayTable.this.size(); 8341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 8351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 8361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public boolean contains(Object value) { 8371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return containsValue(value); 8381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 8391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 8401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 8411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private static final long serialVersionUID = 0; 8421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert} 843