当您开始对groovy中的集合使用gpath处理时,您正在处理的数据类型的确切类型可能会让人感到困惑(至少对我而言)-通常在groovy中,您仅使用“ Duck type”(鸭子类型),一切正常,但是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)
我最大的困惑是,即使将分组“转换”为GroupedTable,该闭包签名也不起作用:
grouped.collect{String modelName, Table subTable->…}
它会在运行时中断,因为即使我使用“ as GroupedTable”转换了分组对象,它也没有将groupBy返回的值从LinkedLists转换为表。
如果我使用闭包签名,它会起作用:
grouped.collect{String modelName, LinkedList subTable->…}
,但其他所有地方似乎都能自动转换。我尝试将“,subTable as Table”指定为“”,但这对于闭包而言无效。
所以我想知道是否有一种方法可以提供从LinkedList到表的“自动”转换,还是可以轻松地处理GroupedTable使其包含值而不是LinkedLists的表
一小部分自动转换可以使Row,Table和GroupedTable更加顺畅地工作,这是我理想的解决方案,但是我不认为asType()会这样做,因为我需要将其应用于LinkedList而不是表格(无论如何,它可能都需要显式的“ as”转换。)
更新-我刚刚在GroupedTable中制作了一个“修复”方法,该方法似乎可以解决问题,但是笨拙!
def fix(){keyset().each{put(it, get(it) as Table)}}
答案 0 :(得分:1)
我不知道为什么自动类型转换不起作用
但是,您可以@Override
这样的groupBy
方法:
(比尔克编辑-这就是我实施达格特的建议的方式)
class Table extends ArrayList<Row> {
GroupedTable groupBy(Closure closure)
def gt=DefaultGroovyMethods.groupBy(this as Iterable, closure) as GroupedTable
gt.changeTypeOfAllValuesToTable()
return gt
static Table build(Iterable list){
return list.collect{it as Row} as Table
}
}
class GroupedTable extends LinkedHashMap<String, Table> {
GroupedTable changeTypeOfAllValuesToTable()
this.keySet().each{String k->
Table t=Table.build(get(k))
put(k, t)
return this
}
稍加努力(如果有人感兴趣的话,可以发布它),我将所有这些都与@TypeChecked注释一起使用。我可能会清理它们,并从中制作出更多有用的类。