日期在 Groovy 中的数组映射
Array Maps with Dates in Groovy
我正在使用 Groovy 并且想要一个包含地图数组的变量。
该变量称为 "Schedule",它是一个映射数组,其中包含 2 个参数,代码和日期
def Schedule = [:]
每个地图都包含 ["code": xx, "date": yy]
,其中代码是 0 到 1000 之间的整数,日期是 DateTime 对象。
我知道地图在存储 DateTime 对象时存在问题,因为它们是基于 JSON 的,所以对我来说最有效的方法是:
- 将新地图对象添加到计划数组
- 通过代码从数组中检索地图对象
- 从数组中按代码删除地图对象
我知道其中一些可能非常基础,但我对管理其中包含 DateTime 的地图对象数组感到困惑。
考虑定义您自己的 class 名称,例如Schedule
- 它是类型安全的,并且比某些未指定的 Map
实例更好用。其次,您可以使用组合 Jackson
+ Joda-Time
。看看我在下面放的例子:
@Grab(group='joda-time', module='joda-time', version='2.7')
@Grab(group='com.fasterxml.jackson.datatype', module='jackson-datatype-joda', version='2.5.1')
import groovy.transform.EqualsAndHashCode
import org.joda.time.DateTime
import com.fasterxml.jackson.databind.ObjectMapper
import com.fasterxml.jackson.datatype.joda.JodaModule
import com.fasterxml.jackson.core.type.TypeReference
@EqualsAndHashCode
class Schedule {
final int code
final DateTime dateTime
// Just to keep this example simple we satisfy jackson
// deserializer with default constructor - consider using
// builder or custom deserializer
Schedule() {}
Schedule(int code, DateTime dateTime) {
this.code = code
this.dateTime = dateTime
}
}
// Use Jackson's ObjectMapper with registered Joda date converter
ObjectMapper objectMapper = new ObjectMapper()
objectMapper.registerModule(new JodaModule())
// Exemplary date
DateTime dateTime = DateTime.parse('2015-02-10T10:05:03.021+01:00')
Schedule schedule = new Schedule(50, dateTime)
String json = objectMapper.writeValueAsString(schedule)
Schedule scheduleFromJson = objectMapper.readValue(json, Schedule)
assert schedule == scheduleFromJson
// Let's try it out with array
def schedules = [schedule, new Schedule(100, DateTime.now())]
String jsonArray = objectMapper.writeValueAsString(schedules)
println jsonArray
def schedulesFromJson = objectMapper.readValue(jsonArray, new TypeReference<List<Schedule>>(){})
assert schedules == schedulesFromJson
要点文件:https://gist.github.com/wololock/18eedc30426e36a6a995
将 Jackson
与已注册的 Joda-Time
类型转换器一起使用,您可以在 class 中使用 DateTime
等对象来保存特定日期。出于多种原因,建议使用 Joda-Time
而不是 java.util.Date
。它是线程安全的(因为不变性),使用起来更简单,例如 Joda-Time
您可以轻松地将日期从一个时区转换为另一个时区等。
然后你所要做的就是创建你的 Schedule
对象,将它们添加到集合中,你可以忘记解析到 JSON 并从 JSON 字符串中读取它们。
PS:如果你使用 JDK 8 你可能会忘记 Joda-Time
并使用新的 java.time
API http://www.oracle.com/technetwork/articles/java/jf14-date-time-2125367.html 我不确定 Jackson
如何转换这些新类型,到目前为止还没有使用它。也许您将不得不添加一些额外的类型转换器,您将不得不检查它。
听起来您可能只需要一个没有代码的普通旧地图。像这样:
import org.joda.time.DateTime
x = [:]
// Add a couple entries
x.put('19', DateTime.now())
x.put('121', DateTime.now().plusDays(4))
// Retrieve an entry
println x.get('19')
// Remove an entry
x.remove('121')
// etc...
println x
我正在使用 Groovy 并且想要一个包含地图数组的变量。
该变量称为 "Schedule",它是一个映射数组,其中包含 2 个参数,代码和日期
def Schedule = [:]
每个地图都包含 ["code": xx, "date": yy]
,其中代码是 0 到 1000 之间的整数,日期是 DateTime 对象。
我知道地图在存储 DateTime 对象时存在问题,因为它们是基于 JSON 的,所以对我来说最有效的方法是:
- 将新地图对象添加到计划数组
- 通过代码从数组中检索地图对象
- 从数组中按代码删除地图对象
我知道其中一些可能非常基础,但我对管理其中包含 DateTime 的地图对象数组感到困惑。
考虑定义您自己的 class 名称,例如Schedule
- 它是类型安全的,并且比某些未指定的 Map
实例更好用。其次,您可以使用组合 Jackson
+ Joda-Time
。看看我在下面放的例子:
@Grab(group='joda-time', module='joda-time', version='2.7')
@Grab(group='com.fasterxml.jackson.datatype', module='jackson-datatype-joda', version='2.5.1')
import groovy.transform.EqualsAndHashCode
import org.joda.time.DateTime
import com.fasterxml.jackson.databind.ObjectMapper
import com.fasterxml.jackson.datatype.joda.JodaModule
import com.fasterxml.jackson.core.type.TypeReference
@EqualsAndHashCode
class Schedule {
final int code
final DateTime dateTime
// Just to keep this example simple we satisfy jackson
// deserializer with default constructor - consider using
// builder or custom deserializer
Schedule() {}
Schedule(int code, DateTime dateTime) {
this.code = code
this.dateTime = dateTime
}
}
// Use Jackson's ObjectMapper with registered Joda date converter
ObjectMapper objectMapper = new ObjectMapper()
objectMapper.registerModule(new JodaModule())
// Exemplary date
DateTime dateTime = DateTime.parse('2015-02-10T10:05:03.021+01:00')
Schedule schedule = new Schedule(50, dateTime)
String json = objectMapper.writeValueAsString(schedule)
Schedule scheduleFromJson = objectMapper.readValue(json, Schedule)
assert schedule == scheduleFromJson
// Let's try it out with array
def schedules = [schedule, new Schedule(100, DateTime.now())]
String jsonArray = objectMapper.writeValueAsString(schedules)
println jsonArray
def schedulesFromJson = objectMapper.readValue(jsonArray, new TypeReference<List<Schedule>>(){})
assert schedules == schedulesFromJson
要点文件:https://gist.github.com/wololock/18eedc30426e36a6a995
将 Jackson
与已注册的 Joda-Time
类型转换器一起使用,您可以在 class 中使用 DateTime
等对象来保存特定日期。出于多种原因,建议使用 Joda-Time
而不是 java.util.Date
。它是线程安全的(因为不变性),使用起来更简单,例如 Joda-Time
您可以轻松地将日期从一个时区转换为另一个时区等。
然后你所要做的就是创建你的 Schedule
对象,将它们添加到集合中,你可以忘记解析到 JSON 并从 JSON 字符串中读取它们。
PS:如果你使用 JDK 8 你可能会忘记 Joda-Time
并使用新的 java.time
API http://www.oracle.com/technetwork/articles/java/jf14-date-time-2125367.html 我不确定 Jackson
如何转换这些新类型,到目前为止还没有使用它。也许您将不得不添加一些额外的类型转换器,您将不得不检查它。
听起来您可能只需要一个没有代码的普通旧地图。像这样:
import org.joda.time.DateTime
x = [:]
// Add a couple entries
x.put('19', DateTime.now())
x.put('121', DateTime.now().plusDays(4))
// Retrieve an entry
println x.get('19')
// Remove an entry
x.remove('121')
// etc...
println x