接口返回的是 json 对象,结构大致如下:
{ extra: { key1: value1, key2: value2 } }
extra 字段是固定的, 但是 key1 和 key2 是运营在后台配置的,安卓客户端拿到接口返回的对象后需要解析出来 key1 和 key2 上报到服务器, 但是安卓客户端同事说无法做这样的动态解析,或者很麻烦,解决方案就是固定 key1 和 key2,或者改变数据结构.
我是前端,这个对于 js 来说就是一个解构符的事情,为什么对于 java 来说这么难呢?
1
ewBuyVmLZMZE 2020-02-16 09:04:42 +08:00 2
|
2
manami 2020-02-16 09:07:06 +08:00 via Android
不难。可以先把 json 转 list,然后动态解析取值就很简单了
|
4
SakuraOjosama 2020-02-16 09:13:01 +08:00
倒是不难,无非就是这边遍历一下,
用 JSONObject 会容易点,用 Gson 的话就。。。 |
5
zy445566 2020-02-16 09:31:09 +08:00 via Android
一个是裹脚布,一个是火葬场。五十笑一百了
|
6
zy445566 2020-02-16 09:32:56 +08:00 via Android
如果 value1 和 value2 类型还不固定,Map 用个锤子
|
7
xxoolltt 2020-02-16 10:07:04 +08:00 via iPhone
json ?
|
9
hhhsuan 2020-02-16 10:20:23 +08:00
不管难不难,最好都别这么写,破坏了语义。
|
10
rockyou12 2020-02-16 10:34:39 +08:00
会影响数据结构与 json 解析效率,但一般 map 就可以解决。实在不行还可以用 jackson 里的 jsonnode 这种 api,但固定字段才是比较好的做法
|
11
zzzmode 2020-02-16 10:39:18 +08:00
解析没问题,考虑的是代码逻辑怎么上报,这种没法需要区分 key1 和 key2 的代表的含义
|
12
yiqunz 2020-02-16 10:40:30 +08:00
楼主是不是没说明白什么叫 key1,key2 不固定
不固定能否枚举?还是 value 性质的 key ? 能枚举那是正常情况应该不会有这种疑问,估计是不能枚举? value 性质的 key 这样设计我忍不了。。。如果 key 需要逻辑处理代码风格会不忍直视。。。 那么问题来了:为什么 key 不固定?能否固定? |
13
jinhan13789991 2020-02-16 10:43:48 +08:00 via Android 3
{ extra: [{ name:key1,value:value1 },{name:key2,value:value2} ]}
这样不香吗? |
14
yiqunz 2020-02-16 10:43:49 +08:00
https://www.v2ex.com/t/629474
关于 json 风格的讨论 请查阅 |
15
luckylo 2020-02-16 10:50:29 +08:00 via Android
归根结底。还是数据结构设计问题
|
16
binux 2020-02-16 10:52:49 +08:00 via Android
归根结底。还是菜
|
17
mcfog 2020-02-16 11:50:06 +08:00 via Android
这事情对 js 确实不难,可是楼主你自己好好想想,key1 key2 是动态的你怎么个用解构拿里面的值
|
18
sagaxu 2020-02-16 12:02:18 +08:00 via Android
不难,但是脏啊,这样的接口得捏着鼻子调用
|
19
abcbuzhiming 2020-02-16 12:32:44 +08:00
key 都不固定的? key 不固定我怎么知道你那个键代表啥意思?怎么会出现 key 都不固定的设计?
这是哪个设计的,键盘砸它脸上去 |
20
charlieputon 2020-02-16 12:36:14 +08:00 via Android
心疼你们安卓,遇到你这样写接口的真是倒了霉了。
|
21
clf 2020-02-16 12:55:05 +08:00
可以做到,且很容易的,做不到就是真的菜。
使用 jackson 或者 fastjson 将 { key1: value1, key2: value2 } 转换为 Map。 Map.keySet()能获得所有的 key 值,Map.entrySet()获取所有的<K, V>键值对。 |
22
serge001 OP @mcfog 不好意思 这里表达的不是很准确 跟解构确实没关系 我这样是因为上报的对象里面有其他固定字段 所以直接解构这个 extra 对象合并另外几个固定字段
|
23
serge001 OP @yiqunz 确实是接口设计的不够合理 不改接口原因是这个接口已经存在比较久了 前端别的地方已经接入
|
24
wwwjf 2020-02-16 13:23:08 +08:00 via Android
有一说一,在 Android 上处理这种接口数据确实比较蛋疼,最近半年都在处理这种数据,也是多端都使用了很久的接口
|
25
clf 2020-02-16 13:25:10 +08:00
@serge001
其实我觉得这样的数据结构设计没啥问题。jsonObject 本来就是一个特殊的键值对的 list。 获取指定 key 的键值对是最快的,每个语言都提供了遍历键值对的方式,只不过你们的安卓开发不会而已。 @jinhan13789991 你这样设计有一个很明显的问题,假设数据里一共有 n 个键值对,我获得某个键值对的时间复杂度是 O(n),而使用楼主的存储方式哈希映射下时间复杂度是 O(1)。 |
26
anxiousPumpkin 2020-02-16 13:36:32 +08:00
public Map<String, Object> extra;
这样就好啦,然后遍历 map 即可获取 key1、key2 |
27
rosu 2020-02-16 13:37:49 +08:00
有一说一,如果真如楼主内容说的:key 和 value 都是字符串,那么问题不大。无非用 Map<String, String> 接然后遍历上报。
但是如果 value1 和 value2 里面是一个对象的话,那就比较蛋疼了;如果还要取对象里的值的话,那就更加蛋疼;如果 Android 这边用的是 Gson,那就非常蛋疼了。 之前遇到,同一个 key,返回不同类型的 value。分别是 String 和 Object。处理起来贼麻烦。 |
28
learningman 2020-02-16 13:39:06 +08:00 via Android
key 本身就不应该带值。。。什么鬼设计
|
29
wwwjf 2020-02-16 13:47:19 +08:00 via Android
@lychs1998 虽然动态 key 数据时间复杂度是 O(1),但是接下来还要对数据做转换,转成对应的实体类对象,还是要循环 n 次,时间复杂度还是 O(n)
|
30
clf 2020-02-16 14:14:06 +08:00
@wwwjf
Map 转换成实体的时间复杂度和 Map 无关,和目标类型含有的字段数有关。 假设 Map 里有 n 个键值对,目标类型里有 m 个属性。转换的时间复杂度是 O(m),逻辑是查询 m 次属性名对应的值。 假设 List 里有 n 个键值对,目标类型有 m 个属性。转换的逻辑是提出每一个属性名,去 list 中遍历是否存在这样的 key 值,时间复杂度应该是 O(m*n)。 |
31
clf 2020-02-16 14:22:03 +08:00
@rosu
这样解析我用 fastjson 写过的,甚至还解析了 List 里套 List。可以参考我的开源项目的 CatContainer 对象的 put 方法的调用链: https://github.com/lychs1998/CatMock |
32
rosu 2020-02-16 14:55:59 +08:00 via iPhone
@lychs1998 感谢回复。看了您的代码,实现方式就是遍历取值建立映射。我们之前也考虑过这样实现。唯一担心的还是耗时问题。如果直接把 json 丢进去转,正如您上面说的,时间复杂度会是 O(m*n )。如果 json 数据比较多(列表信息之类),可能会有潜在的性能问题。(只是有这个感性担忧,没有量化)。
所以我们当时的做法是兼容接口,因为这样的接口是少数,所以采用手动解析的方式,只遍历和取值到业务需要的键值。 不过您的代码对我也有很大启发,非常感谢~ |
33
Aresxue 2020-02-16 16:11:39 +08:00
不难
|
34
tairan2006 2020-02-16 17:45:12 +08:00
后端用 JsonNode 比较常见…如果不好处理就把 key 和 value 做成数组吧
|
35
serge001 OP @yiqunz 因为 key 跟 value 都是产品 /运营在后台配置的,是埋点的自定义数据, 确实接口设计成 key/value 的数组是比较合理的. 但是对于前端来说设计成对象写起来的确会方便很多
|
38
wysnylc 2020-03-14 17:10:34 +08:00
json 四种类型 字符串 数字 对象 数组
对应 java String BigDecimal Map Collection 你不会不代表没有 |