日期在 Groovy 中的数组映射

Array Maps with Dates in Groovy

我正在使用 Groovy 并且想要一个包含地图数组的变量。 该变量称为 "Schedule",它是一个映射数组,其中包含 2 个参数,代码和日期 def Schedule = [:]

每个地图都包含 ["code": xx, "date": yy],其中代码是 0 到 1000 之间的整数,日期是 DateTime 对象。

我知道地图在存储 DateTime 对象时存在问题,因为它们是基于 JSON 的,所以对我来说最有效的方法是:

  1. 将新地图对象添加到计划数组
  2. 通过代码从数组中检索地图对象
  3. 从数组中按代码删除地图对象

我知道其中一些可能非常基础,但我对管理其中包含 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