Groovy 中的列表迭代
首先,我将 清单 3 中的 List 重构为 Groovy。在这里,只需要直接对列表调用 each() 方法并传递一个闭包,而不是将 List 转换成 for 循环(顺便提一句,这样做并不是特别具有面向对象的特征,不是吗)。
创建一个名为 listTest.groovy 的文件并添加清单 4 中的代码:
清单 4. Groovy 列表迭代
list.each{language->
println language
}
清单 4 中的第一行是 Groovy 用于构建 java.util.ArrayList 的便捷语法。可以将 println list.class 添加到此脚本来验证这一点。接下来,只需对列表调用 each(),并在闭包体内输出 language 变量。在闭包的开始处使用 language-> 语句命名 language 变量。如果没有提供变量名,Groovy 提供了一个默认名称 it。在命令行提示符中输入 groovy listTest 运行 listTest.groovy。
清单 5 是经过简化的 清单 4 代码版本:
清单 5. 使用 Groovy 的 it 变量的迭代
def list = ["Java", "Groovy", "JavaScript"]
list.each{ println it }
// shorter still, using an anonymous list
["Java", "Groovy", "JavaScript"].each{ println it }
Groovy 允许您对数组和 List 交替使用 each() 方法。为了将 ArrayList 改为 String 数组,必须将 as String[] 添加到行末,如清单 6 所示:
清单 6. Groovy 数组迭代
list.each{println it}
在 Groovy 中普遍使用 each() 方法,并且 getter 语法非常便捷(getClass() 和 class 是相同的调用),这使您能够编写既简洁又富有表达性的代码。例如,假设您希望利用反射显示给定类的所有公共方法。清单 7 展示了这个例子:
清单 7. Groovy 反射
println s
println s.class
s.class.methods.each{println it}
//output:
$ groovy reflectionTest.groovy
Hello World
class java.lang.String
public int java.lang.String.hashCode()
public volatile int java.lang.String.compareTo(java.lang.Object)
public int java.lang.String.compareTo(java.lang.String)
public boolean java.lang.String.equals(java.lang.Object)
...
脚本的最后一行调用 getClass() 方法。java.lang.Class 提供了一个 getMethods() 方法,后者返回一个数组。通过将这些操作串连起来并对 Method 的结果数组调用 each(),您只使用了一行代码就完成了大量工作。
但是,与 Java for-each 语句不同的是,功能较多的 each() 方法并不仅限于 List 和数组。在 Java 语言中,故事到此结束。然而,在 Groovy 中,故事才刚刚开始。