gpt4 book ai didi

android - 如何在 json 反序列化期间从列表中删除某些元素?

转载 作者:行者123 更新时间:2023-11-29 22:38:18 26 4
gpt4 key购买 nike

假设我们有一个 api 调用,它给我一个对象列表(例如 Person (name: String, surname: String, age: String))和不一致的服务(age in第一项为字符串,第二项为 Int)响应为:

{
"people":[
{
"name":"Jon",
"surname":"Snow",
"age":"34"
},
{
"name":"Ted",
"surname":"Mosby",
"age":35
}
]
}

是否可以使用自定义类型适配器/使用 gson 库的反序列化从列表中删除格式错误的元素?如果是,最好的方法是什么?

最佳答案

您可以通过使用自定义 TypeAdapter 来实现因为它可以让您决定如何处理 JsonReader 返回的标记.

假设你有一个类型 Response表示您在上面粘贴的 JSON 字符串(类似于 class Result(val people: List<Person>) ),我认为这里的关键是提供一个 TypeAdapter<List<Person>> ,因为这样可以过滤掉无效的 Person对象——你不能简单地创建一个 TypeAdapter<Person>返回 null无效值 Person对象为 people被定义为不可空对象列表(即 List<Person> 而不是 List<Person?>

上述概念的证明是:

data class Person(val name: String, val surname: String, val age: String)
class Result(val people: List<Person>)

fun main() {
val json = """
{
"people":[
{
"name":"Jon",
"surname":"Snow",
"age":"34"
},
{
"name":"Ted",
"surname":"Mosby",
"age":35
},
{
"name":"John",
"surname":"Smith",
"age": "40"
}
]
}""".trimIndent()

val gson = GsonBuilder().registerTypeAdapterFactory(PersonListTypeAdapterFactory).create()

val result = gson.fromJson(json, Result::class.java)
println("Deserialized: ${result.people}")
println("Serialized: ${gson.toJson(result)}")
}

object PersonListTypeAdapterFactory : TypeAdapterFactory {
override fun <T : Any?> create(gson: Gson, type: TypeToken<T>): TypeAdapter<T>? {
if (type.rawType != List::class.java || (type as? ParameterizedType)?.actualTypeArguments?.contains(Person::class.java) == false) {
return null
}
val delegate: TypeAdapter<List<Person>> = gson.getDelegateAdapter(this, type) as TypeAdapter<List<Person>>
return PersonListTypeAdapter(delegate) as TypeAdapter<T>
}
}

class PersonListTypeAdapter(private val delegate: TypeAdapter<List<Person>>) : TypeAdapter<List<Person>>() {

override fun write(out: JsonWriter, value: List<Person>) {
delegate.write(out, value)
}

override fun read(input: JsonReader): List<Person> {
input.beginArray()
val people = mutableListOf<Person>()
while (input.peek() != JsonToken.END_ARRAY) {
val person = readPerson(input)
if (person != null) {
people.add(person)
}
}
input.endArray()

return people
}

private fun readPerson(input: JsonReader): Person? {
input.beginObject()

// initialising everything with nulls is a bit ugly
var name: String? = null
var surname: String? = null
var age: String? = null

var token = input.peek()
while (token != JsonToken.END_OBJECT) {
when (input.nextName()) {
"name" -> name = input.nextString()
"surname" -> surname = input.nextString()
"age" -> {
token = input.peek()
age = if (token == JsonToken.STRING) {
input.nextString()
} else {
input.skipValue()
// logging if needed
null
}
}
}
token = input.peek()
}
input.endObject()

if (listOf(name, surname, age).none(Objects::isNull)) {
return Person(name!!, surname!!, age!!)
}
return null
}

}

该代码将打印:

Deserialized: [Person(name=Jon, surname=Snow, age=34), Person(name=John, surname=Smith, age=40)]
Serialized: {"people":[{"name":"Jon","surname":"Snow","age":"34"},{"name":"John","surname":"Smith","age":"40"}]}

我很确定还有很大的改进空间😄

关于android - 如何在 json 反序列化期间从列表中删除某些元素?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59308913/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com