I'm not sure I understand your question correctly. Perhaps something like this is what you are looking for:
def things = [ [name: 'aaa', title: '222'], [name: 'aaa', title: '333'], [title: '222'], [title: '111'], [name: 'bbb', title: '111'], [title: '333'], [name: 'aaa', title: '111'], ] things.sort { a, b -> // Compare by name and then by title. a.name <=> b.name ?: a.title <=> b.title } assert things == [ [title: '111'], [title: '222'], [title: '333'], [name: 'aaa', title: '111'], [name: 'aaa', title: '222'], [name: 'aaa', title: '333'], [name: 'bbb', title: '111'], ]
What happens inside this seemingly innocent comparison function is actually quite a bit of Groovy syntax magic. But it is not too difficult.
First, the sort method is called using a binary function that acts as a comparator (i.e., it takes two arguments: a and b and returns -1 if a <b, 1 if a> b and 0 if a = = b).
This anonymous function: { a, b -> a.name <=> b.name ?: a.title <=> b.title } uses the spacecraft operator "( <=> ... that man is a spaceship!) before first compare a and b by name.
If the names are equal (or both are equal to zero), then the result a.name <=> b.name is 0, which is falsely calculated in the Elvis operator "( ?: ... imagine it as an emoticon), so the result is a.title <=> b.title .
Otherwise, if the result of the comparison of names is not equal to 0, then this is fairly evaluated in the Elvis operator and this value is returned.
This is all, given that you can compare null values with strings and that 'any string' > null always executed (this is the same as saying that 'any string' <=> null == 1 ).
So, the end result is that elements without a name are first sorted by title, and then elements with a name and a name are sorted first by name and then by name.
Hope this was what you were looking for. If you were expecting a different order of sorted items, feel free to clarify it in the comments :)
Update
There is also an undocumented OrderBy object that can be used in this case:
things.sort new OrderBy([{it.name}, {it.title}])