我正在开发一个项目,该项目将以专有格式读取某些数据,将其收集到一些统一的Groovy数据结构中,并以整齐的XML(或JSON,尚未决定)格式写出来。 我是Groovy的新手,但是,这个项目是Ant构建项目,Groovy似乎是最好的方法。
到目前为止,我能够读取数据,创建原子结构,使用>>连接它们。运算符,并使用MarkupBuilder将它们无缝地转储到XML(比我在Java中使用它更容易)。但是,当我需要稍微修改收集的结构,或者遍历它们以组成一些聚合数据时,我现在陷入困境。
为了说明,假设我们收集了数据,因此它等同于:
def inventory = {
car (make: "Subaru", model: "Impreza WRX", year: 2010, color: "Blue") {
feature ("Premium sound")
feature ("Brembo brakes")
bug ("Leaks oil")
bug ("Needs new transmission")
}
car (make: "Jeep", model: "Wrangler", year: 13, awd: true) {
feature ("Soft top")
bug ("Doesn't start")
bug ("Flooded")
}
// blahblahblah
}
我们正努力实现以下目标,例如:
所以我们最终得到这样的结构:
def inventory = {
car (make: "Subaru", model: "Impreza WRX", year: 2010, color: "Blue") {
feature ("Premium sound")
feature ("Brembo brakes")
}
car (make: "Jeep", model: "Wrangler", year: 2013) {
feature ("AWD")
feature ("Soft top")
}
// blahblahblah
}
实际上,我可以通过原始结构组成一个新列表(我的数据不是那么大,需要就地编辑),但是我如何首先遍历这个结构呢? / p>
哦,还有一个术语问题。也许,我只是在谷歌上搜索一个错误的关键字...这个实体在代码中定义:它也被称为“闭包”,或者它有一个不同的术语吗?
答案 0 :(得分:1)
看inventory
,它实际上可以用
@Immutable(copyWith = true)
class Car {
String make
String model
int year
String color
boolean awd
List<String> features
List<String> bugs
}
由于你可以编写一个新列表(并且一般说来没有理由不这样做),你可以添加@Immutable
注释。作为一种副作用&#34;您可以添加copyWith = true
来获取复制方法。
inventory
的定义可能如下所示:
def inventory = [
new Car(
make: "Subaru",
model: "Impreza WRX",
year: 2010,
color: "Blue",
features: ["Premium sound", "Brembo brakes"],
bugs: ["Leaks oil", "Needs new transmission"]),
new Car(
make: "Jeep",
model: "Wrangler",
year: 13,
awd: true,
features: ["Soft top"],
bugs: ["Doesn't start", "Flooded"])
]
它为您提供了不可变的数据表示。 然后,您可以使用集合API遍历和更改数据。在你的情况下:
def result = inventory
.collect { it.copyWith(bugs: []) }
.collect { it.copyWith(year:
it.year < 2000 ? it.year + 2000 : it.year) }
.collect {
if (it.awd) {
it.copyWith(features: it.features + "AWD")
} else {
it
}
每个转换都是单独应用的(并且只有不可变的实例流经该管道)。
如果您确实要删除空错误列表和/或awd
属性,请定义目标类:
class FixedCar {
String make
String model
int year
String color
List<String> features
static FixedCar apply(Car car) {
new FixedCar(
make: car.make,
model: car.model,
year: car.year,
color: car.color,
features: car.features)
}
}
并向collect
添加另一个电话:
def result = inventory
.collect { it.copyWith(bugs: []) }
.collect { it.copyWith(year:
it.year < 2000 ? it.year + 2000 : it.year) }
.collect {
if (it.awd) {
it.copyWith(features: it.features + "AWD")
} else {
it
}
}.collect { FixedCar.apply(it) }