Kotlin中字符串转回Map出现双括号问题的原因及解决方法
问题
我有一个Map类型的dataMap,其中名为currentSessionData的值是一个被转换为字符串的Map。我需要将该字符串转回Map,编写了如下代码:
private fun loadData() { val directory = File(this.filesDir, "savefiles") if (directory.exists()) { Files.walk(Paths.get(directory.toString())).filter { Files.isRegularFile(it) }.forEach { var data = it.inputStream().readBytes().toString(Charsets.UTF_8) val dataMap = JSONObject(data).toMap() Log.d("datamap", dataMap.toString()) val currentSessionData = dataMap["sessionData"] val map = currentSessionData!!.split(",").associate { val (left, right) = it.split("=") left to right } Log.d("mymap", map.toString()) } } }
但日志输出结果为:{{name=2023-07-08 18:32:03, dateAndTime=2023-07-08 18:32:05, time=871, distance=18, setsNumber=10, arrowsPer=3, type=target, place=emptyPlace, numOfArchers=1}},由于存在双括号,无法正常访问其中的键值对。请问该问题的成因是什么?如何消除双括号并得到正常的Map?
问题成因
双括号是因为currentSessionData的原始字符串本身就被一对大括号包裹着(比如格式是{name=xxx, dateAndTime=xxx...}),你直接用逗号分割处理时,第一个元素会带上左大括号(变成{name=2023-07-08 18:32:03),最后一个元素会带上右大括号(变成 numOfArchers=1})。当associate生成Map后,toString()输出时就会把这两个带括号的键值对包含进去,最终出现双括号的效果。
解决方法
处理currentSessionData前,先去掉首尾的大括号,再做分割转换,同时注意清理键值对前后的空格:
private fun loadData() { val directory = File(this.filesDir, "savefiles") if (directory.exists()) { Files.walk(Paths.get(directory.toString())).filter { Files.isRegularFile(it) }.forEach { val data = it.inputStream().readBytes().toString(Charsets.UTF_8) val dataMap = JSONObject(data).toMap() Log.d("datamap", dataMap.toString()) // 空安全处理+去除首尾大括号 val currentSessionData = dataMap["sessionData"]?.toString() ?: return@forEach val cleanedData = currentSessionData.trim().removeSurrounding("{", "}") val map = cleanedData.split(",").associate { pairStr -> // 分割键值对并清理空格 val (key, value) = pairStr.trim().split("=") key.trim() to value.trim() } Log.d("mymap", map.toString()) } } }
关键处理点:
- 用
removeSurrounding("{", "}")精准去掉字符串首尾的大括号 - 每一步都用
trim()清理空格,避免键名或值里混入多余空格 - 增加空安全判断,防止
currentSessionData为null时触发空指针异常
内容的提问来源于stack exchange,提问作者Jayne
相关产品推荐
相关产品推荐

