aboutsummaryrefslogtreecommitdiffstats
path: root/guava/src/com/google/common/collect/RegularImmutableTable.java
diff options
context:
space:
mode:
Diffstat (limited to 'guava/src/com/google/common/collect/RegularImmutableTable.java')
-rw-r--r--guava/src/com/google/common/collect/RegularImmutableTable.java564
1 files changed, 154 insertions, 410 deletions
diff --git a/guava/src/com/google/common/collect/RegularImmutableTable.java b/guava/src/com/google/common/collect/RegularImmutableTable.java
index e4bfb70..c6ae3eb 100644
--- a/guava/src/com/google/common/collect/RegularImmutableTable.java
+++ b/guava/src/com/google/common/collect/RegularImmutableTable.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009 The Guava Authors
+ * Copyright (C) 2009 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -21,11 +21,11 @@ import static com.google.common.base.Preconditions.checkNotNull;
import com.google.common.annotations.GwtCompatible;
import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.Function;
import com.google.common.base.Objects;
import java.util.Collections;
import java.util.Comparator;
-import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
@@ -36,63 +36,56 @@ import javax.annotation.concurrent.Immutable;
* An implementation of {@link ImmutableTable} holding an arbitrary number of
* cells.
*
- * @author Gregory Kick
+ * @author gak@google.com (Gregory Kick)
*/
@GwtCompatible
abstract class RegularImmutableTable<R, C, V> extends ImmutableTable<R, C, V> {
- private RegularImmutableTable() {}
-
- private transient ImmutableCollection<V> values;
+ private final ImmutableSet<Cell<R, C, V>> cellSet;
- @Override public final ImmutableCollection<V> values() {
- ImmutableCollection<V> result = values;
- return (result == null) ? values = createValues() : result;
+ private RegularImmutableTable(ImmutableSet<Cell<R, C, V>> cellSet) {
+ this.cellSet = cellSet;
}
-
- abstract ImmutableCollection<V> createValues();
- @Override public abstract int size();
+ private static final Function<Cell<Object, Object, Object>, Object>
+ GET_VALUE_FUNCTION =
+ new Function<Cell<Object, Object, Object>, Object>() {
+ @Override public Object apply(Cell<Object, Object, Object> from) {
+ return from.getValue();
+ }
+ };
+
+ @SuppressWarnings("unchecked")
+ private Function<Cell<R, C, V>, V> getValueFunction() {
+ return (Function) GET_VALUE_FUNCTION;
+ }
- @Override public final boolean containsValue(@Nullable Object value) {
- return values().contains(value);
+ @Nullable private transient volatile ImmutableList<V> valueList;
+
+ @Override public final ImmutableCollection<V> values() {
+ ImmutableList<V> result = valueList;
+ if (result == null) {
+ valueList = result = ImmutableList.copyOf(
+ Iterables.transform(cellSet(), getValueFunction()));
+ }
+ return result;
}
-
- private transient ImmutableSet<Cell<R, C, V>> cellSet;
- @Override
- public final ImmutableSet<Cell<R, C, V>> cellSet() {
- ImmutableSet<Cell<R, C, V>> result = cellSet;
- return (result == null) ? cellSet = createCellSet() : result;
+ @Override public final int size() {
+ return cellSet().size();
}
-
- abstract ImmutableSet<Cell<R, C, V>> createCellSet();
-
- abstract class CellSet extends ImmutableSet<Cell<R, C, V>> {
- @Override
- public int size() {
- return RegularImmutableTable.this.size();
- }
-
- @Override
- public boolean contains(@Nullable Object object) {
- if (object instanceof Cell) {
- Cell<?, ?, ?> cell = (Cell<?, ?, ?>) object;
- Object value = get(cell.getRowKey(), cell.getColumnKey());
- return value != null && value.equals(cell.getValue());
- }
- return false;
- }
- @Override
- boolean isPartialView() {
- return false;
- }
+ @Override public final boolean containsValue(@Nullable Object value) {
+ return values().contains(value);
}
@Override public final boolean isEmpty() {
return false;
}
+ @Override public final ImmutableSet<Cell<R, C, V>> cellSet() {
+ return cellSet;
+ }
+
static final <R, C, V> RegularImmutableTable<R, C, V> forCells(
List<Cell<R, C, V>> cells,
@Nullable final Comparator<? super R> rowComparator,
@@ -137,13 +130,15 @@ abstract class RegularImmutableTable<R, C, V> extends ImmutableTable<R, C, V> {
forCellsInternal(Iterable<Cell<R, C, V>> cells,
@Nullable Comparator<? super R> rowComparator,
@Nullable Comparator<? super C> columnComparator) {
+ ImmutableSet.Builder<Cell<R, C, V>> cellSetBuilder = ImmutableSet.builder();
ImmutableSet.Builder<R> rowSpaceBuilder = ImmutableSet.builder();
ImmutableSet.Builder<C> columnSpaceBuilder = ImmutableSet.builder();
- ImmutableList<Cell<R, C, V>> cellList = ImmutableList.copyOf(cells);
- for (Cell<R, C, V> cell : cellList) {
+ for (Cell<R, C, V> cell : cells) {
+ cellSetBuilder.add(cell);
rowSpaceBuilder.add(cell.getRowKey());
columnSpaceBuilder.add(cell.getColumnKey());
}
+ ImmutableSet<Cell<R, C, V>> cellSet = cellSetBuilder.build();
ImmutableSet<R> rowSpace = rowSpaceBuilder.build();
if (rowComparator != null) {
@@ -160,9 +155,9 @@ abstract class RegularImmutableTable<R, C, V> extends ImmutableTable<R, C, V> {
// use a dense table if more than half of the cells have values
// TODO(gak): tune this condition based on empirical evidence
- return (cellList.size() > ((rowSpace.size() * columnSpace.size()) / 2)) ?
- new DenseImmutableTable<R, C, V>(cellList, rowSpace, columnSpace) :
- new SparseImmutableTable<R, C, V>(cellList, rowSpace, columnSpace);
+ return (cellSet.size() > ((rowSpace.size() * columnSpace.size()) / 2 )) ?
+ new DenseImmutableTable<R, C, V>(cellSet, rowSpace, columnSpace) :
+ new SparseImmutableTable<R, C, V>(cellSet, rowSpace, columnSpace);
}
/**
@@ -175,52 +170,50 @@ abstract class RegularImmutableTable<R, C, V> extends ImmutableTable<R, C, V> {
private final ImmutableMap<R, Map<C, V>> rowMap;
private final ImmutableMap<C, Map<R, V>> columnMap;
- private final int[] iterationOrderRow;
- private final int[] iterationOrderColumn;
- SparseImmutableTable(ImmutableList<Cell<R, C, V>> cellList,
- ImmutableSet<R> rowSpace, ImmutableSet<C> columnSpace) {
- Map<R, Integer> rowIndex = Maps.newHashMap();
- Map<R, Map<C, V>> rows = Maps.newLinkedHashMap();
- for (R row : rowSpace) {
- rowIndex.put(row, rows.size());
- rows.put(row, new LinkedHashMap<C, V>());
- }
- Map<C, Map<R, V>> columns = Maps.newLinkedHashMap();
- for (C col : columnSpace) {
- columns.put(col, new LinkedHashMap<R, V>());
+ /**
+ * Creates a {@link Map} over the key space with
+ * {@link ImmutableMap.Builder}s ready for values.
+ */
+ private static final <A, B, V> Map<A, ImmutableMap.Builder<B, V>>
+ makeIndexBuilder(ImmutableSet<A> keySpace) {
+ Map<A, ImmutableMap.Builder<B, V>> indexBuilder = Maps.newLinkedHashMap();
+ for (A key : keySpace) {
+ indexBuilder.put(key, ImmutableMap.<B, V>builder());
}
- int[] iterationOrderRow = new int[cellList.size()];
- int[] iterationOrderColumn = new int[cellList.size()];
- for (int i = 0; i < cellList.size(); i++) {
- Cell<R, C, V> cell = cellList.get(i);
+ return indexBuilder;
+ }
+
+ /**
+ * Builds the value maps of the index and creates an immutable copy of the
+ * map.
+ */
+ private static final <A, B, V> ImmutableMap<A, Map<B, V>> buildIndex(
+ Map<A, ImmutableMap.Builder<B, V>> indexBuilder) {
+ return ImmutableMap.copyOf(Maps.transformValues(indexBuilder,
+ new Function<ImmutableMap.Builder<B, V>, Map<B, V>>() {
+ @Override public Map<B, V> apply(ImmutableMap.Builder<B, V> from) {
+ return from.build();
+ }
+ }));
+ }
+
+ SparseImmutableTable(ImmutableSet<Cell<R, C, V>> cellSet,
+ ImmutableSet<R> rowSpace, ImmutableSet<C> columnSpace) {
+ super(cellSet);
+ Map<R, ImmutableMap.Builder<C, V>> rowIndexBuilder
+ = makeIndexBuilder(rowSpace);
+ Map<C, ImmutableMap.Builder<R, V>> columnIndexBuilder
+ = makeIndexBuilder(columnSpace);
+ for (Cell<R, C, V> cell : cellSet) {
R rowKey = cell.getRowKey();
C columnKey = cell.getColumnKey();
V value = cell.getValue();
-
- iterationOrderRow[i] = rowIndex.get(rowKey);
- Map<C, V> thisRow = rows.get(rowKey);
- iterationOrderColumn[i] = thisRow.size();
- V oldValue = thisRow.put(columnKey, value);
- if (oldValue != null) {
- throw new IllegalArgumentException("Duplicate value for row=" + rowKey + ", column="
- + columnKey + ": " + value + ", " + oldValue);
- }
- columns.get(columnKey).put(rowKey, value);
- }
- this.iterationOrderRow = iterationOrderRow;
- this.iterationOrderColumn = iterationOrderColumn;
- ImmutableMap.Builder<R, Map<C, V>> rowBuilder = ImmutableMap.builder();
- for (Map.Entry<R, Map<C, V>> row : rows.entrySet()) {
- rowBuilder.put(row.getKey(), ImmutableMap.copyOf(row.getValue()));
+ rowIndexBuilder.get(rowKey).put(columnKey, value);
+ columnIndexBuilder.get(columnKey).put(rowKey, value);
}
- this.rowMap = rowBuilder.build();
-
- ImmutableMap.Builder<C, Map<R, V>> columnBuilder = ImmutableMap.builder();
- for (Map.Entry<C, Map<R, V>> col : columns.entrySet()) {
- columnBuilder.put(col.getKey(), ImmutableMap.copyOf(col.getValue()));
- }
- this.columnMap = columnBuilder.build();
+ this.rowMap = buildIndex(rowIndexBuilder);
+ this.columnMap = buildIndex(columnIndexBuilder);
}
@Override public ImmutableMap<R, V> column(C columnKey) {
@@ -272,153 +265,6 @@ abstract class RegularImmutableTable<R, C, V> extends ImmutableTable<R, C, V> {
Map<C, V> row = rowMap.get(rowKey);
return (row == null) ? null : row.get(columnKey);
}
-
- @Override
- ImmutableCollection<V> createValues() {
- return new ImmutableList<V>() {
- @Override
- public int size() {
- return iterationOrderRow.length;
- }
-
- @Override
- public V get(int index) {
- int rowIndex = iterationOrderRow[index];
- ImmutableMap<C, V> row = (ImmutableMap<C, V>) rowMap.values().asList().get(rowIndex);
- int columnIndex = iterationOrderColumn[index];
- return row.values().asList().get(columnIndex);
- }
-
- @Override
- boolean isPartialView() {
- return true;
- }
- };
- }
-
- @Override
- public int size() {
- return iterationOrderRow.length;
- }
-
- @Override
- ImmutableSet<Cell<R, C, V>> createCellSet() {
- return new SparseCellSet();
- }
-
- class SparseCellSet extends CellSet {
- @Override
- public UnmodifiableIterator<Cell<R, C, V>> iterator() {
- return asList().iterator();
- }
-
- @Override
- ImmutableList<Cell<R, C, V>> createAsList() {
- return new ImmutableAsList<Cell<R, C, V>>() {
- @Override
- public Cell<R, C, V> get(int index) {
- int rowIndex = iterationOrderRow[index];
- Map.Entry<R, Map<C, V>> rowEntry = rowMap.entrySet().asList().get(rowIndex);
- ImmutableMap<C, V> row = (ImmutableMap<C, V>) rowEntry.getValue();
- int columnIndex = iterationOrderColumn[index];
- Map.Entry<C, V> colEntry = row.entrySet().asList().get(columnIndex);
- return Tables.immutableCell(rowEntry.getKey(), colEntry.getKey(), colEntry.getValue());
- }
-
- @Override
- ImmutableCollection<Cell<R, C, V>> delegateCollection() {
- return SparseCellSet.this;
- }
- };
- }
- }
- }
-
- /**
- * An immutable map implementation backed by an indexed nullable array, used in
- * DenseImmutableTable.
- */
- private abstract static class ImmutableArrayMap<K, V> extends ImmutableMap<K, V> {
- private final int size;
-
- ImmutableArrayMap(int size) {
- this.size = size;
- }
-
- abstract ImmutableMap<K, Integer> keyToIndex();
-
- // True if getValue never returns null.
- private boolean isFull() {
- return size == keyToIndex().size();
- }
-
- K getKey(int index) {
- return keyToIndex().keySet().asList().get(index);
- }
-
- @Nullable abstract V getValue(int keyIndex);
-
- @Override
- ImmutableSet<K> createKeySet() {
- return isFull() ? keyToIndex().keySet() : super.createKeySet();
- }
-
- @Override
- public int size() {
- return size;
- }
-
- @Override
- public V get(@Nullable Object key) {
- Integer keyIndex = keyToIndex().get(key);
- return (keyIndex == null) ? null : getValue(keyIndex);
- }
-
- @Override
- ImmutableSet<Entry<K, V>> createEntrySet() {
- if (isFull()) {
- return new ImmutableMapEntrySet<K, V>() {
- @Override ImmutableMap<K, V> map() {
- return ImmutableArrayMap.this;
- }
-
- @Override
- public UnmodifiableIterator<Entry<K, V>> iterator() {
- return new AbstractIndexedListIterator<Entry<K, V>>(size()) {
- @Override
- protected Entry<K, V> get(int index) {
- return Maps.immutableEntry(getKey(index), getValue(index));
- }
- };
- }
- };
- } else {
- return new ImmutableMapEntrySet<K, V>() {
- @Override ImmutableMap<K, V> map() {
- return ImmutableArrayMap.this;
- }
-
- @Override
- public UnmodifiableIterator<Entry<K, V>> iterator() {
- return new AbstractIterator<Entry<K, V>>() {
- private int index = -1;
- private final int maxIndex = keyToIndex().size();
-
- @Override
- protected Entry<K, V> computeNext() {
- for (index++; index < maxIndex; index++) {
- V value = getValue(index);
- if (value != null) {
- return Maps.immutableEntry(getKey(index), value);
- }
- }
- return endOfData();
- }
- };
- }
- };
- }
- }
}
/**
@@ -428,20 +274,14 @@ abstract class RegularImmutableTable<R, C, V> extends ImmutableTable<R, C, V> {
static final class DenseImmutableTable<R, C, V>
extends RegularImmutableTable<R, C, V> {
- private final ImmutableMap<R, Integer> rowKeyToIndex;
- private final ImmutableMap<C, Integer> columnKeyToIndex;
- private final ImmutableMap<R, Map<C, V>> rowMap;
- private final ImmutableMap<C, Map<R, V>> columnMap;
- private final int[] rowCounts;
- private final int[] columnCounts;
+ private final ImmutableBiMap<R, Integer> rowKeyToIndex;
+ private final ImmutableBiMap<C, Integer> columnKeyToIndex;
private final V[][] values;
- private final int[] iterationOrderRow;
- private final int[] iterationOrderColumn;
- private static <E> ImmutableMap<E, Integer> makeIndex(
+ private static <E> ImmutableBiMap<E, Integer> makeIndex(
ImmutableSet<E> set) {
- ImmutableMap.Builder<E, Integer> indexBuilder =
- ImmutableMap.builder();
+ ImmutableBiMap.Builder<E, Integer> indexBuilder =
+ ImmutableBiMap.builder();
int i = 0;
for (E key : set) {
indexBuilder.put(key, i);
@@ -450,19 +290,15 @@ abstract class RegularImmutableTable<R, C, V> extends ImmutableTable<R, C, V> {
return indexBuilder.build();
}
- DenseImmutableTable(ImmutableList<Cell<R, C, V>> cellList,
+ DenseImmutableTable(ImmutableSet<Cell<R, C, V>> cellSet,
ImmutableSet<R> rowSpace, ImmutableSet<C> columnSpace) {
+ super(cellSet);
@SuppressWarnings("unchecked")
V[][] array = (V[][]) new Object[rowSpace.size()][columnSpace.size()];
this.values = array;
this.rowKeyToIndex = makeIndex(rowSpace);
this.columnKeyToIndex = makeIndex(columnSpace);
- rowCounts = new int[rowKeyToIndex.size()];
- columnCounts = new int[columnKeyToIndex.size()];
- int[] iterationOrderRow = new int[cellList.size()];
- int[] iterationOrderColumn = new int[cellList.size()];
- for (int i = 0; i < cellList.size(); i++) {
- Cell<R, C, V> cell = cellList.get(i);
+ for (Cell<R, C, V> cell : cellSet) {
R rowKey = cell.getRowKey();
C columnKey = cell.getColumnKey();
int rowIndex = rowKeyToIndex.get(rowKey);
@@ -471,113 +307,25 @@ abstract class RegularImmutableTable<R, C, V> extends ImmutableTable<R, C, V> {
checkArgument(existingValue == null, "duplicate key: (%s, %s)", rowKey,
columnKey);
values[rowIndex][columnIndex] = cell.getValue();
- rowCounts[rowIndex]++;
- columnCounts[columnIndex]++;
- iterationOrderRow[i] = rowIndex;
- iterationOrderColumn[i] = columnIndex;
- }
- this.iterationOrderRow = iterationOrderRow;
- this.iterationOrderColumn = iterationOrderColumn;
- this.rowMap = new RowMap();
- this.columnMap = new ColumnMap();
- }
-
- private final class Row extends ImmutableArrayMap<C, V> {
- private final int rowIndex;
-
- Row(int rowIndex) {
- super(rowCounts[rowIndex]);
- this.rowIndex = rowIndex;
- }
-
- @Override
- ImmutableMap<C, Integer> keyToIndex() {
- return columnKeyToIndex;
- }
-
- @Override
- V getValue(int keyIndex) {
- return values[rowIndex][keyIndex];
- }
-
- @Override
- boolean isPartialView() {
- return true;
- }
- }
-
- private final class Column extends ImmutableArrayMap<R, V> {
- private final int columnIndex;
-
- Column(int columnIndex) {
- super(columnCounts[columnIndex]);
- this.columnIndex = columnIndex;
- }
-
- @Override
- ImmutableMap<R, Integer> keyToIndex() {
- return rowKeyToIndex;
- }
-
- @Override
- V getValue(int keyIndex) {
- return values[keyIndex][columnIndex];
- }
-
- @Override
- boolean isPartialView() {
- return true;
- }
- }
-
- private final class RowMap extends ImmutableArrayMap<R, Map<C, V>> {
- private RowMap() {
- super(rowCounts.length);
- }
-
- @Override
- ImmutableMap<R, Integer> keyToIndex() {
- return rowKeyToIndex;
- }
-
- @Override
- Map<C, V> getValue(int keyIndex) {
- return new Row(keyIndex);
- }
-
- @Override
- boolean isPartialView() {
- return false;
- }
- }
-
- private final class ColumnMap extends ImmutableArrayMap<C, Map<R, V>> {
- private ColumnMap() {
- super(columnCounts.length);
- }
-
- @Override
- ImmutableMap<C, Integer> keyToIndex() {
- return columnKeyToIndex;
- }
-
- @Override
- Map<R, V> getValue(int keyIndex) {
- return new Column(keyIndex);
- }
-
- @Override
- boolean isPartialView() {
- return false;
}
}
@Override public ImmutableMap<R, V> column(C columnKey) {
- Integer columnIndex = columnKeyToIndex.get(checkNotNull(columnKey));
- if (columnIndex == null) {
+ checkNotNull(columnKey);
+ Integer columnIndexInteger = columnKeyToIndex.get(columnKey);
+ if (columnIndexInteger == null) {
return ImmutableMap.of();
} else {
- return new Column(columnIndex);
+ // unbox only once
+ int columnIndex = columnIndexInteger;
+ ImmutableMap.Builder<R, V> columnBuilder = ImmutableMap.builder();
+ for (int i = 0; i < values.length; i++) {
+ V value = values[i][columnIndex];
+ if (value != null) {
+ columnBuilder.put(rowKeyToIndex.inverse().get(i), value);
+ }
+ }
+ return columnBuilder.build();
}
}
@@ -585,8 +333,31 @@ abstract class RegularImmutableTable<R, C, V> extends ImmutableTable<R, C, V> {
return columnKeyToIndex.keySet();
}
+ private transient volatile ImmutableMap<C, Map<R, V>> columnMap;
+
+ private ImmutableMap<C, Map<R, V>> makeColumnMap() {
+ ImmutableMap.Builder<C, Map<R, V>> columnMapBuilder =
+ ImmutableMap.builder();
+ for (int c = 0; c < columnKeyToIndex.size(); c++) {
+ ImmutableMap.Builder<R, V> rowMapBuilder = ImmutableMap.builder();
+ for (int r = 0; r < rowKeyToIndex.size(); r++) {
+ V value = values[r][c];
+ if (value != null) {
+ rowMapBuilder.put(rowKeyToIndex.inverse().get(r), value);
+ }
+ }
+ columnMapBuilder.put(columnKeyToIndex.inverse().get(c),
+ rowMapBuilder.build());
+ }
+ return columnMapBuilder.build();
+ }
+
@Override public ImmutableMap<C, Map<R, V>> columnMap() {
- return columnMap;
+ ImmutableMap<C, Map<R, V>> result = columnMap;
+ if (result == null) {
+ columnMap = result = makeColumnMap();
+ }
+ return result;
}
@Override public boolean contains(@Nullable Object rowKey,
@@ -616,7 +387,15 @@ abstract class RegularImmutableTable<R, C, V> extends ImmutableTable<R, C, V> {
if (rowIndex == null) {
return ImmutableMap.of();
} else {
- return new Row(rowIndex);
+ ImmutableMap.Builder<C, V> rowBuilder = ImmutableMap.builder();
+ V[] row = values[rowIndex];
+ for (int r = 0; r < row.length; r++) {
+ V value = row[r];
+ if (value != null) {
+ rowBuilder.put(columnKeyToIndex.inverse().get(r), value);
+ }
+ }
+ return rowBuilder.build();
}
}
@@ -624,66 +403,31 @@ abstract class RegularImmutableTable<R, C, V> extends ImmutableTable<R, C, V> {
return rowKeyToIndex.keySet();
}
- @Override
- public ImmutableMap<R, Map<C, V>> rowMap() {
- return rowMap;
- }
+ private transient volatile ImmutableMap<R, Map<C, V>> rowMap;
- @Override
- ImmutableCollection<V> createValues() {
- return new ImmutableList<V>() {
- @Override
- public int size() {
- return iterationOrderRow.length;
- }
-
- @Override
- public V get(int index) {
- return values[iterationOrderRow[index]][iterationOrderColumn[index]];
- }
-
- @Override
- boolean isPartialView() {
- return true;
+ private ImmutableMap<R, Map<C, V>> makeRowMap() {
+ ImmutableMap.Builder<R, Map<C, V>> rowMapBuilder = ImmutableMap.builder();
+ for (int r = 0; r < values.length; r++) {
+ V[] row = values[r];
+ ImmutableMap.Builder<C, V> columnMapBuilder = ImmutableMap.builder();
+ for (int c = 0; c < row.length; c++) {
+ V value = row[c];
+ if (value != null) {
+ columnMapBuilder.put(columnKeyToIndex.inverse().get(c), value);
+ }
}
- };
- }
-
- @Override
- public int size() {
- return iterationOrderRow.length;
- }
-
- @Override
- ImmutableSet<Cell<R, C, V>> createCellSet() {
- return new DenseCellSet();
- }
-
- class DenseCellSet extends CellSet {
- @Override
- public UnmodifiableIterator<Cell<R, C, V>> iterator() {
- return asList().iterator();
+ rowMapBuilder.put(rowKeyToIndex.inverse().get(r),
+ columnMapBuilder.build());
}
+ return rowMapBuilder.build();
+ }
- @Override
- ImmutableList<Cell<R, C, V>> createAsList() {
- return new ImmutableAsList<Cell<R, C, V>>() {
- @Override
- public Cell<R, C, V> get(int index) {
- int rowIndex = iterationOrderRow[index];
- int columnIndex = iterationOrderColumn[index];
- R rowKey = rowKeySet().asList().get(rowIndex);
- C columnKey = columnKeySet().asList().get(columnIndex);
- V value = values[rowIndex][columnIndex];
- return Tables.immutableCell(rowKey, columnKey, value);
- }
-
- @Override
- ImmutableCollection<Cell<R, C, V>> delegateCollection() {
- return DenseCellSet.this;
- }
- };
+ @Override public ImmutableMap<R, Map<C, V>> rowMap() {
+ ImmutableMap<R, Map<C, V>> result = rowMap;
+ if (result == null) {
+ rowMap = result = makeRowMap();
}
+ return result;
}
}
}