Groovy 宇宙飞船运算符
最后修改于 2025 年 3 月 20 日
Groovy 中的宇宙飞船运算符 <=>
简化了比较,根据左操作数是否小于、等于或大于右操作数,返回 -1、0 或 1。它非常适合排序和自定义比较,提高了可读性,优于传统方法。本教程将通过示例探讨其用法。
数值比较
宇宙飞船运算符比较两个值,产生一个整数结果,指示它们的相对顺序,使其直观易懂,适合基本检查。
def a = 5 def b = 8 println a <=> b // Output: -1 println b <=> a // Output: 1 println a <=> a // Output: 0
a <=> b
比较 5 和 8:5 < 8,所以结果是 -1。b <=> a
给出 1 (8 > 5),而 a <=> a
是 0 (5 = 5)。这些结果模仿了 Java 的 compareTo
,但运算符的语法更简洁且视觉上更清晰。
按长度对字符串进行排序
宇宙飞船运算符在排序方面表现出色,尤其是在闭包中,它允许根据属性对字符串列表等集合进行自定义排序。
def words = ['sky', 'water', 'emotion', 'shredder', 'anonymous', 'on', 'a', 'copper', 'the', 'elephant'] words.sort { e1, e2 -> e1.length() <=> e2.length() } println words words.sort { e1, e2 -> e2.length() <=> e1.length() } println words
e1.length() <=> e2.length()
按字符串长度升序排序 words
:从 "a" (1) 到 "anonymous" (9)。通过 e2.length() <=> e1.length()
反向排序,则按降序排序:从 "anonymous" 到 "a"。运算符的输出 (-1, 0, 1) 控制排序顺序,展示了其在自定义比较中的强大功能。
$ groovy SortByLength.groovy [a, on, sky, the, water, copper, emotion, shredder, elephant, anonymous] [anonymous, elephant, shredder, emotion, copper, water, the, sky, on, a]
排序自定义对象
通过宇宙飞船运算符实现 Comparable
接口,可以对自定义对象进行排序,以自然、可重用的方式比较它们的属性。
class User implements Comparable { String fname String lname String occupation User(String fname, String lname, String occupation) { this.fname = fname this.lname = lname this.occupation = occupation } int compareTo(o) { this.lname <=> o.lname } String toString() { "${fname} ${lname} - ${occupation}" } } def users = [ new User('John', 'Doe', 'gardener'), new User('Roger', 'Roe', 'driver'), new User('Lucia', 'Smith', 'accountant'), new User('Paul', 'Newman', 'firefighter'), new User('Adam', 'Clapton', 'teacher'), new User('Jane', 'Walter', 'pilot') ] println users println users.sort()
User
类在 compareTo
方法中使用 this.lname <=> o.lname
来按姓氏排序。sort()
方法按字母顺序对 users
进行排序:从 "Clapton" 到 "Walter"。宇宙飞船运算符按字典顺序比较字符串,与 Groovy 的自定义对象排序方法无缝集成。
$ groovy SortUsers.groovy [John Doe - gardener, Roger Roe - driver, Lucia Smith - accountant, Paul Newman - firefighter, Adam Clapton - teacher, Jane Walter - pilot] [Adam Clapton - teacher, John Doe - gardener, Paul Newman - firefighter, Roger Roe - driver, Lucia Smith - accountant, Jane Walter - pilot]
比较混合类型
宇宙飞船运算符可以优雅地处理混合类型,根据需要转换操作数,这使其对于异构数据比较非常通用。
def values = [5, "10", 3.14, "2"] values.sort { a, b -> a <=> b } println values
a <=> b
对混合类型(整数、字符串、浮点数)的 values
进行排序。Groovy 在可能的情况下将字符串强制转换为数字,结果为 [3.14, "2", 5, "10"]。数字比较优先,显示了该运算符在处理类型多样性方面的灵活性。
$ groovy MixedTypes.groovy [3.14, 2, 5, 10]
使用宇宙飞船进行过滤
除了排序,宇宙飞船运算符还可以通过与阈值进行比较来过滤集合,利用其在条件逻辑中的数值输出。
def numbers = [15, 7, 22, 3, 19, 10] def threshold = 12 def above = numbers.findAll { it <=> threshold > 0 } println above
it <=> threshold > 0
查找大于 12 的数字。如果 it <=> threshold
的结果是 1 (it > 12),则该数字被包含在内,结果为 [15, 22, 19]。这直接在过滤器中使用运算符的结果,将其用途从排序扩展到选择任务。
$ groovy FilterSpaceship.groovy [15, 22, 19]
自定义多属性排序
宇宙飞船运算符可以链接比较来进行多标准排序,在主要标准相同时比较次要属性,从而提供精细的控制。
class Product { String name int price Product(String name, int price) { this.name = name this.price = price } String toString() { "${name} (\$${price})" } } def products = [ new Product("Laptop", 1200), new Product("Mouse", 25), new Product("Laptop", 800), new Product("Keyboard", 50) ] products.sort { a, b -> def nameCmp = a.name <=> b.name nameCmp != 0 ? nameCmp : a.price <=> b.price } println products
a.name <=> b.name
首先按名称排序。如果名称相等(0
),则 a.price <=> b.price
来打破平局。 "Laptop" 按价格 (800, 1200) 排序,然后是 "Keyboard" 和 "Mouse"。这演示了运算符的链接能力在分层排序中的应用。
$ groovy MultiSort.groovy [Laptop ($800), Laptop ($1200), Keyboard ($50), Mouse ($25)]
宇宙飞船在条件逻辑中的应用
运算符的 -1、0、1 输出可以驱动 if-else 逻辑,提供一种紧凑的方式来对值之间的关系进行分类,而无需进行多次比较。
def x = 7 def y = 10 def result = (x <=> y) switch { -1 -> "less than" 0 -> "equal to" 1 -> "greater than" } println "$x is $result $y" // Output: 7 is less than 10
x <=> y
(7 < 10) 返回 -1,通过 switch 映射为 "小于"。这避免了单独的 <
、==
、>
检查,使用运算符的结果简洁地描述了 x
和 y
之间的关系。
来源
本教程涵盖了 Groovy 宇宙飞船运算符 <=>
,展示了其在排序、过滤和自定义比较中的应用,并附带实际示例。
作者
列出 所有 Groovy 教程。