Когда вы начинаете использовать обработку gpath для коллекций в groovy, то, какой именно тип структуры данных вы имеете дело, может несколько запутать (по крайней мере, для меня) - обычно в 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 был «преобразован» в 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 вместо таблицы (и в любом случае, вероятно, потребуется явное преобразование «как»)
Обновление - я только что сделал метод "исправления" в GroupedTable, который, кажется, решает проблему, но неуклюж!
def fix(){keyset().each{put(it, get(it) as Table)}}