如何按现有属性对列表进行排序

ajs*_*sie 9 java sorting groovy

我在这里使用这一行来根据对象的名称对列表进行排序.

g.V.sort{it.name}
Run Code Online (Sandbox Code Playgroud)

如果它存在,我如何根据"名称"对其进行排序,如果不存在,我想按"标题"对其进行排序.如果两者都存在,我想首先按"名称"排序,然后按"标题"排序.

我不是一个Groovy编码器,所以感谢您的帮助.

epi*_*ian 13

我不确定我是否理解你的问题.也许这就是你要找的东西:

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'],
]
Run Code Online (Sandbox Code Playgroud)

在这个看似无辜的比较函数中发生的事实实际上是很多Groovy语法魔法.但这并不难理解.

首先,sort使用充当比较器的二进制函数调用该方法(即,如果a <b,则返回-1,如果a> b则返回-1,如果a = b,则返回0).

这个匿名函数:{ a, b -> a.name <=> b.name ?: a.title <=> b.title }使用" 宇宙飞船运营商 "(<=>......那是一个宇宙飞船的人!)首先用名字比较a和b.

如果名称相等(或两者都为null),则结果a.name <=> b.name为0,在" Elvis运算符 "中错误地计算(?:...将其想象为笑脸),然后a.title <=> b.title返回结果.

否则,如果名称比较的结果不是0,那么在Elvis运算符中如实评估并返回该值.

这一切都考虑到你可以比较空值和字符串,并'any string' > null始终保持(这与说明相同'any string' <=> null == 1).

因此,最终结果是没有名称的元素首先按标题排序,然后具有名称和标题的元素首先按名称排序,然后按标题排序.

我希望那就是你要找的东西.如果您期望排序元素的不同排序,请随时在评论中澄清:)

更新

OrderBy在这种情况下还可以使用一个没有很好记录的对象:

things.sort new OrderBy([{it.name}, {it.title}])
Run Code Online (Sandbox Code Playgroud)

  • 我想你可以解释"如果它存在"意味着"不是空",你怎么方便:) (2认同)

Art*_*ero 5

您可以使用a对Collection进行排序Comparator.

g.V.sort { a, b ->
    a.name <=> b.name ?: a.title <=> b.title
}
Run Code Online (Sandbox Code Playgroud)