当您开始在groovy中对集合使用gpath处理时,您所处理的数据结构的确切类型可能会有点混乱(至少对我来说)——通常在groovy中您只使用“Duck-typing”,一切都可以正常工作,但Duck-typing实际上会损害编码人员对变量在任何时间点可能包含的内容的理解。
Map<String, List<Map<String, String>>>
它实际上是一种非常常见(并且非常有用)的中间结构,但是在代码中查看它的人并没有得到真正的帮助。(如果不明显,它的行为很像一个索引/分组sql表,我打赌它不是)
在向同事解释我的代码(并试图自己理解代码)时,我创建了一些新类型,以更清楚地说明我的意图:
class Row extends LinkedHashMap<String, String>{} // Record--like a row in a table
class Table extends ArrayList<Row>{} // A table--like an SQL table. A list of rows
class GroupedTable extends LinkedHashMap<String, Table> // A map of tables indexed by some name using groupBy()
这项工作出人意料地好。在定义这些之后,我可以说:
Table t=sql.rows(someQuery) as Table
Row r=t.get(0)
GroupedTable grouped= t.groupBy{it.an_sql_column} as GroupedTable
有时我不必手动强制值(如行中的值),有时我会强制值(如GroupedTable中的值),这有点令人困惑,但它通常可以工作(即使启用@TypeChecked)
grouped.collect{String modelName, Table subTable->â¦}
它将在运行时中断,因为即使我使用“as GroupedTable”转换了分组对象,它也没有将groupBy从LinkedList返回的值转换为表。
如果我使用闭包签名,它会起作用:
grouped.collect{String modelName, LinkedList subTable->â¦}
因此,我想知道是否有一种方法可以提供从LinkedList到table的“自动”转换,或者轻松地处理GroupedTable,使其包含用于其值的表,而不是LinkedList
我的理想解决方案是使用一小部分自动转换,使行、表和GroupedTable工作得更顺畅,但我认为asType()无法做到这一点,因为我需要将其应用于LinkedList而不是Table(而且可能无论如何都需要显式的“as”转换)
更新——我刚刚在GroupedTable中创建了一个“修复”方法,它似乎可以修复问题,但很笨拙!
def fix(){keyset().each{put(it, get(it) as Table)}}