Reputation: 382
I have a Map data structure as mentioned below. I want to convert this into Table. I am trying to achieve this using Tables.newCustomTable()
method but getting below error.
Exception in thread "main" java.lang.IllegalArgumentException
at com.google.common.base.Preconditions.checkArgument(Preconditions.java:111)
at com.google.common.collect.Tables.newCustomTable(Tables.java:299)
The Code is:
public class TestClass {
public static void main(String[] args) {
Map<Integer, Map<Integer, String>> data = Maps.newHashMap();
Map<Integer, String> internalMap = Maps.newHashMap();
internalMap.put(1, "A");
internalMap.put(2, "B");
internalMap.put(3, "C");
data.put(1, internalMap);
data.put(2, internalMap);
data.put(3, internalMap);
Table<Integer, Integer, String> table = table(data);
System.out.println(table);
}
public static <R, C, V> Table<R, C, V> table(Map<R, Map<C, V>> toTable) {
return Tables.newCustomTable(toTable, new Supplier<Map<C, V>>() {
@Override
public Map<C, V> get() {
return Maps.newLinkedHashMap();
}
});
}
}
Upvotes: 2
Views: 3453
Reputation: 382
public static <R, C, V> Table<R, C, V> table(Map<R, Map<C, V>> fromTable)
{
Table<R, C, V> table = HashBasedTable.create();
for (R rowKey : fromTable.keySet())
{
Map<C, V> rowMap = fromTable.get(rowKey);
for (C columnKey : rowMap.keySet())
{
V value = rowMap.get(columnKey);
table.put(rowKey, columnKey, value);
}
}
return table;
}
Upvotes: 1
Reputation: 20618
The documentation of Tables.newCustomTable
clearly says:
Throws:
IllegalArgumentException - if backingMap is not empty
So you must provide an empty map, but you filled it with some data.
EDIT as per the comments:
The method Tables.newCustomTable
does not transform an already data containing map into a table view. It is used for a more custom behavior when it comes to create the underyling maps. In fact, the method Tables.newCustomTable
only gives more control over the concrete type of maps that should be created for rows and columns. For example, it can be used as following:
public static <R extends Comparable<R>, C, V> Table<R, C, V> createTable() {
return Tables.newCustomTable(Maps.newTreeMap(), new Supplier<Map<C, V>>() {
@Override
public Map<C, V> get() {
return Maps.newLinkedHashMap();
}
});
}
Note that I used TreeMap
for the rows and LinkedHashMap
for the columns. (I needed to constrain the type parameter R to extend Comparable
, by the way.)
In most cases you do not need that behavior and thus you can write your method as following:
public static <R, C, V> Table<R, C, V> table(Map<R, Map<C, V>> fromTable)
{
Table<R, C, V> table = HashBasedTable.create();
for (R rowKey : fromTable.keySet())
{
Map<C, V> rowMap = fromTable.get(rowKey);
for (C columnKey : rowMap.keySet())
{
V value = rowMap.get(columnKey);
table.put(rowKey, columnKey, value);
}
}
return table;
}
Upvotes: 2