我有一个Map数据结构,如下所述。我想将其转换为表格。我正在尝试使用Tables.newCustomTable()
方法实现此目的,但出现错误以下。
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)
该代码是:
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();
}
});
}
}
最佳答案
Tables.newCustomTable
的documentation明确指出:
Throws:
IllegalArgumentException - if backingMap is not empty
因此,您必须提供一个空的地图,但要用一些数据填充它。
根据评论进行编辑:
方法
Tables.newCustomTable
不会将已经包含数据的映射转换为表格视图。用于创建底图时,它用于更自定义的行为。实际上,方法Tables.newCustomTable
仅对应为行和列创建的地图的具体类型提供更多控制。例如,可以按以下方式使用: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();
}
});
}
请注意,我在行中使用
TreeMap
,在列中使用LinkedHashMap
。 (顺便说一下,我需要限制类型参数R扩展Comparable
。)在大多数情况下,您不需要该行为,因此可以按以下方式编写方法:
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;
}