对象数组与对象的对象
问题是要决定下列符号之间的权衡:
基于JSON :
"users": { "id1": { "id": "id1", "firstname": "firstname1", "lastname": "lastname1" }, "id2": { "id": "id2", "firstaame": "firstname2", "lastname": "lastname2" } }
基于arrays :
users: [ { "id": "id", "key2": "value2", "key3": "value3" }, { "id": "id", "key2": "value2", "key3": "value3" } ]
关于同一个问题上的这篇文章,我决定(在前端)使用JSON对象符号而不是对象数组,因为它适合我的要求,更好的性能和更less的浏览器代码。
但问题是,列表本身不是静态的。 由此我的意思是正在生成列表,即从数据库(NoSQL)中提取/存储,并通过服务器上的Java API为新条目创build。 我无法决定我应该在后端使用哪种符号(最终也会影响用户界面)。
任何有关性能,可维护性或可扩展性的想法/build议,我们感激不尽。
这是一个总的意见基础的问题。 可能还有很多其他的问题,但我可以指出如下。
基于JSON的方法:如果我没有错,那么这将在服务器端使用Map
来实现。
优点:在JavaScript中你可以直接使用users.id1,users.id2即不需要迭代
缺点:在客户端,一些你将需要在你的JSON中存在的ID,即硬编码或使用一些dynamic的方法,这将告诉你哪个ID是在你的JSON目前。
基于数组的方法:如果我没有错,那么这将在服务器端使用Array
/ List
来实现。
优点:
- 在客户端,你可以直接迭代数组,而不必担心在哪个ID里面存在,也就是说没有硬编码。
- 正如@JBNizet所指出的,基于数组的方法将保持顺序。
缺点:如果你想获取单一的ID,那么你将需要遍历数组。
通常我们不会在客户端发送太多的信息,所以基于数组的方法不会产生任何问题。 如果你想要基于ID的方法,那么可以将数组转换成地图(服务器和客户端) 。
在服务器端,数组存储为简单的列表: ArrayList<Content>
,而对象存储为映射: HashMap<String, Content>
或者大部分存储为Java对象。
为了将Java实体转换成JSON或从JSON转换,你可以看一下Jackson的项目,它为你做了所有的事情。
我不担心这两个变体之间的性能差异。 有一个可理解的语义API是更重要的,所以你应该根据业务案例而不是性能来描述你的需求。
看你的例子,我认为一个Array
是更好的方法,因为你想返回一个用户列表是平等的。 发送id两次没有意义,增加了必须传输的数据量。
此外,由于Arrays
在Java中更容易存储和迭代,所以它们也应该提供比Object更好的性能。
一些一般的区别:
- 数组保存顺序
- 数组可以包含重复的条目
- 对象通常具有更大的存储/networking开销
- 数组的迭代速度更快(在服务器端)
想到你的第一个“基于JSON的”表示法的一个很大的缺点就是某些框架将会出现序列化的问题。 例如,DataContractSerializer(C#.NET)将期望在对象users
的类中定义(硬编码)字段id1
和id2
。 我不确定这是否也适用于某些Java框架。 也许你使用的框架可以将其反序列化为一个HashMap。
总的来说,我会发现数组符号在迭代等方面更加直观。
您可以使用object[property]
符号访问或设置JavaScript中的对象的属性。
在后端使用基于数组的方法,然后将数组转换为前端的映射( 基于JSON )。
var list = [{id: "id1", value: "One"}, {id: "id2", value: "Two"}] var map = {}; list.forEach(function (item) { map[item.id] = item }); map.get("id1")
如果您的列表发生变化,您可以从后端获取新列表并在UI中更新您的地图。
这样你的后端响应速度就会更快,因为它不需要将列表转换为地图。 您的前端将在列表上执行O(n)迭代,将其转换为地图。 但与O(n)相比,这是一个很小的代价,每次在列表中search时都要付钱。
如果你将要在后端使用基于 ID的数据,那么在后端使用JSON Based (你可以使用LinkedHashMap
来保持顺序)。
两种方法都有其优点和缺点,取决于你在看什么。
数组的方法很容易序列化,更“框架”友好(您可以将bean添加到列表中,然后序列化列表,然后完成)。 这允许例如web容器返回响应,而不需要任何定制。 大多数框架可能都支持这种方式。
另一方面,基于对象的方法更难以生成(相对而言),但更容易查找,因为已知键。
所以为了便于实现(由生产者),去基于数组的方法。 为了便于使用(由客户使用)去基于对象的方法。