【问题标题】:Gson how to convert list of known size to multiple fieldsGson如何将已知大小的列表转换为多个字段
【发布时间】:2019-07-22 06:47:44
【问题描述】:

我有一个 Json 格式,例如:

{
  "kind": "prediction",
  "command": "true",
  "logs": [{
    "time_log": "12:00",
    "date": "2019-07-17",
    "prices": [{
      "state": "past",
      "count": "128"
    }, {
      "state": "present",
      "type": "255"
    }, {
      "state": "future",
      "count": "300"
    }]
  }, {
    "time_log": "12:00",
    "date": "2019-07-18",
    "prices": [{
      "state": "past",
      "count": "255"
    }, {
      "state": "present",
      "type": "308"
    }, {
      "state": "future",
      "count": "400"
    }]
  }]
}

Kotlin 中表示解析数据的类是 Response(顶级 JSON)和其他类:

data class Response(
  val kind: String,
  val command: String,
  val logs: List<Log>
)

data class Log(
  val time_log: String,
  val date: String,
  val prices: List<Price>
)

data class Price(
  val state: String,
  val count: String
)

所以当我在没有反序列化器的情况下在 Gson 中正常解析 JSON 文件时,上面的代码可以正常工作。但是,我不希望 Log 类存储 Prices 的列表,因为我确定 prices 数组将仅包含 3 个元素,因此我想将它们中的每一个存储在Log类喜欢:

data class Log(
  val time_log: String,
  val date: String,
  val past_price: Price,
  val present_price: Price,
  val future_price: Price
)

请问如何在 Gson 中做到这一点?我已经尝试了几个小时,但不知道该怎么做。我也不确定是否需要为 Response 类编写反序列化器,这似乎需要做很多工作,还是可以更轻松地完成?任何指针或建议将不胜感激。

【问题讨论】:

标签: java json kotlin gson


【解决方案1】:

最好的当然是更改 API 以更好地反映内容:如果价格列表实际上不是一个列表而是 3 个具体价格,那么它应该首先由 API 以这种方式返回。

如果您不控制 API,避免自定义反序列化程序复杂性的一种简单解决方案是保留列表,但添加几个属性以更方便地访问列表:

data class Log(
  val time_log: String,
  val date: String,
  private val prices: List<Price>
) {
  val pastPrice: Price 
    get() = prices[0]
  val presentPrice: Price 
    get() = prices[1]
  val futurePrice: Price 
    get() = prices[2]
}

【讨论】:

  • 您好,感谢您的回答。直接分配给这些属性(如在您的初始解决方案中)与使用 get() = prices[0] 有什么区别?
  • @WAQT 初始化一个属性意味着该属性将有一个支持字段,从而使Log 类占用更多内存,但该值仅计算一次(在实例化时)。使用 get() 创建一个不受字段支持的属性,它只能通过它的 getter 访问。这意味着它不占用任何内存,因为每次都会计算该值。你只需要选择最适合你的,但在这种情况下,访问列表非常便宜,而且我不认为值得额外的内存。
  • @WAQT 作为旁注,请记住在构造函数之外声明的属性不是生成的equals/hashcode 的一部分
  • 谢谢,但这在我的情况下似乎不起作用,因为我使用Room 库将数据存储到数据库中,而Log 类是Entity。我认为存储在数据库表中的东西不能是属性,但我不太确定。
  • 但是列表你的实体的一个属性,所以也许你只需要在你的情况下删除私有
猜你喜欢
  • 1970-01-01
  • 2016-06-20
  • 1970-01-01
  • 1970-01-01
  • 2023-03-18
  • 1970-01-01
  • 2017-12-26
相关资源
最近更新 更多