如何在 Kotlin 中将地图和嵌套地图转换为字符串,反之亦然?
How to convert map and nested map to string and vise versa in Kotlin?
我不知道如何将 HashMap 和嵌套 Hashmap 转换为字符串,反之亦然:
我使用 Room 将数据保存在本地数据库中。 "users" hashmap 是数据 class 的一个参数。要在Room数据库中保存这个参数"users",我们必须将其转换为原始类型,如string、boolen、Integer等。Room不支持对象引用,所以type converters 是必需的。
val users = HashMap<String, HashMap<String, Any>>()
val user1 = HashMap<String, Any>()
user1["filter"] = 0
user1["group"] = "groupId"
user1["labelsVisibility"] = true
user1["sort"] = 1
user1["view"] = 3
users["user1"] = user1
val user2 = HashMap<String, Any>()
user2["filter"] = 0
user2["group"] = "groupId"
user2["labelsVisibility"] = true
user2["sort"] = 1
user2["view"] = 3
users["user2"] = user2
解决方案
可能有更好的方法来做到这一点,但它有效
使用特殊符号将 HashMap<String, HashMap<String, Any>>
转换为字符串 * + (符号在字符串中必须是唯一的)
fun fromUsersPreferences(users: HashMap<String, HashMap<String, Any>>): String {
var usersString = ""
users.forEach {
usersString = usersString.plus("${it.key}*${it.value}+")
}
usersString = usersString.dropLast(1)
return usersString
}
输出:
"user1*{filter=0, view=3, labelsVisibility=true, sort=1, group=groupId}+user2*{filter=1, view=1, labelsVisibility=false, sort=0, group=groupId}"
将字符串转换为 HashMap<String, HashMap<String, Any>>
fun toUsersPreferences(users: String): HashMap<String, HashMap<String, Any>> {
val usersMap = users.split("+").associateTo(HashMap()){
val list = it.split("*")
val userKey = list[0]
val userValue = list[1].removeSurrounding("{", "}").split(", ").associateTo(HashMap()){
val (key, value) = it.split("=")
if (key.equals("group")) {
Pair<String, Any>(key, value)
} else if (key.equals("labelsVisibility")) {
Pair<String, Any>(key, value.toBoolean())
} else {
Pair<String, Any>(key, value.toInt())
}
}
Pair(userKey, userValue)
}
return usersMap
}
输出:
{user1={filter=0, view=3, labelsVisibility=true, sort=1, group=groupId}, user2={filter=1, view=1, labelsVisibility=false, sort=0, group=groupId}}
正如我之前在评论中所说,可以使用 Gson 库轻松完成:
// Configure Gson
val gson = GsonBuilder()
// Using this strategy Gson first tries converting number to Long.
// If it fails (number is float), then it tries converting to Double
.setObjectToNumberStrategy(ToNumberPolicy.LONG_OR_DOUBLE)
.create()
// Convert to JSON string
val jsonString = gson.toJson(users)
println("JSON => $jsonString")
// Store at Room as a string...
// Fetch later from Room as a string...
val type = object : TypeToken<HashMap<String, HashMap<String, Any>>>() {}.type
val fromJsonMap: HashMap<String, HashMap<String, Any>> = gson.fromJson(jsonString, type)
println("ORIGINAL MAP =>\n$users")
println("RESTORED MAP =>\n$fromJsonMap")
输出:
JSON => {
"user1": {
"filter": 0,
"view": 3,
"labelsVisibility": true,
"sort": 1,
"group": "groupId"
},
"user2": {
"filter": 0,
"view": 3,
"labelsVisibility": true,
"sort": 1,
"group": "groupId"
}
}
ORIGINAL MAP =>
{user1={filter=0, view=3, labelsVisibility=true, sort=1, group=groupId}, user2={filter=0, view=3, labelsVisibility=true, sort=1, group=groupId}}
RESTORED MAP =>
{user1={filter=0, view=3, labelsVisibility=true, sort=1, group=groupId}, user2={filter=0, view=3, labelsVisibility=true, sort=1, group=groupId}}
如您所见,原始地图 users
和恢复后的地图 fromJsonMap
完全相同。
我不知道如何将 HashMap 和嵌套 Hashmap 转换为字符串,反之亦然:
我使用 Room 将数据保存在本地数据库中。 "users" hashmap 是数据 class 的一个参数。要在Room数据库中保存这个参数"users",我们必须将其转换为原始类型,如string、boolen、Integer等。Room不支持对象引用,所以type converters 是必需的。
val users = HashMap<String, HashMap<String, Any>>()
val user1 = HashMap<String, Any>()
user1["filter"] = 0
user1["group"] = "groupId"
user1["labelsVisibility"] = true
user1["sort"] = 1
user1["view"] = 3
users["user1"] = user1
val user2 = HashMap<String, Any>()
user2["filter"] = 0
user2["group"] = "groupId"
user2["labelsVisibility"] = true
user2["sort"] = 1
user2["view"] = 3
users["user2"] = user2
解决方案
可能有更好的方法来做到这一点,但它有效
使用特殊符号将
HashMap<String, HashMap<String, Any>>
转换为字符串 * + (符号在字符串中必须是唯一的)fun fromUsersPreferences(users: HashMap<String, HashMap<String, Any>>): String { var usersString = "" users.forEach { usersString = usersString.plus("${it.key}*${it.value}+") } usersString = usersString.dropLast(1) return usersString }
输出:
"user1*{filter=0, view=3, labelsVisibility=true, sort=1, group=groupId}+user2*{filter=1, view=1, labelsVisibility=false, sort=0, group=groupId}"
将字符串转换为
HashMap<String, HashMap<String, Any>>
fun toUsersPreferences(users: String): HashMap<String, HashMap<String, Any>> { val usersMap = users.split("+").associateTo(HashMap()){ val list = it.split("*") val userKey = list[0] val userValue = list[1].removeSurrounding("{", "}").split(", ").associateTo(HashMap()){ val (key, value) = it.split("=") if (key.equals("group")) { Pair<String, Any>(key, value) } else if (key.equals("labelsVisibility")) { Pair<String, Any>(key, value.toBoolean()) } else { Pair<String, Any>(key, value.toInt()) } } Pair(userKey, userValue) } return usersMap }
输出:
{user1={filter=0, view=3, labelsVisibility=true, sort=1, group=groupId}, user2={filter=1, view=1, labelsVisibility=false, sort=0, group=groupId}}
正如我之前在评论中所说,可以使用 Gson 库轻松完成:
// Configure Gson
val gson = GsonBuilder()
// Using this strategy Gson first tries converting number to Long.
// If it fails (number is float), then it tries converting to Double
.setObjectToNumberStrategy(ToNumberPolicy.LONG_OR_DOUBLE)
.create()
// Convert to JSON string
val jsonString = gson.toJson(users)
println("JSON => $jsonString")
// Store at Room as a string...
// Fetch later from Room as a string...
val type = object : TypeToken<HashMap<String, HashMap<String, Any>>>() {}.type
val fromJsonMap: HashMap<String, HashMap<String, Any>> = gson.fromJson(jsonString, type)
println("ORIGINAL MAP =>\n$users")
println("RESTORED MAP =>\n$fromJsonMap")
输出:
JSON => {
"user1": {
"filter": 0,
"view": 3,
"labelsVisibility": true,
"sort": 1,
"group": "groupId"
},
"user2": {
"filter": 0,
"view": 3,
"labelsVisibility": true,
"sort": 1,
"group": "groupId"
}
}
ORIGINAL MAP =>
{user1={filter=0, view=3, labelsVisibility=true, sort=1, group=groupId}, user2={filter=0, view=3, labelsVisibility=true, sort=1, group=groupId}}
RESTORED MAP =>
{user1={filter=0, view=3, labelsVisibility=true, sort=1, group=groupId}, user2={filter=0, view=3, labelsVisibility=true, sort=1, group=groupId}}
如您所见,原始地图 users
和恢复后的地图 fromJsonMap
完全相同。