对象数组与对象对象
Posted
技术标签:
【中文标题】对象数组与对象对象【英文标题】:Array of objects vs Object of Objects 【发布时间】:2015-10-06 19:09:17 【问题描述】:问题在于决定以下符号之间的权衡:
基于 JSON 的:
"users":
"id1":
"id": "id1",
"firstname": "firstname1",
"lastname": "lastname1"
,
"id2":
"id": "id2",
"firstaame": "firstname2",
"lastname": "lastname2"
基于数组:
users: [
"id": "id",
"key2": "value2",
"key3": "value3"
,
"id": "id",
"key2": "value2",
"key3": "value3"
]
关于同一问题上的this 帖子,我已决定(在前端)使用 JSON 对象表示法而不是对象数组,因为它符合我的要求、更好的性能和更少的浏览器代码。
但问题是列表本身不是静态的。我的意思是正在生成列表,即从数据库(NoSQL)获取/存储,并通过服务器上的 Java API 为新条目创建。我无法决定我应该在后端使用哪种表示法(最终也会影响 UI)。
感谢您对性能、可维护性或可扩展性提出任何想法/建议。
【问题讨论】:
你如何比较这两种方法。在基于 JSON 的情况下,您将值作为 id,在基于数组的情况下,您将其作为数组。你有什么要求? 在 javascript 中,我可以使用id
(对于 JSON)获取对象,但在数组的情况下,我必须遍历整个列表并匹配每个对象的 id
属性,这在大数据集的情况下可能成为瓶颈。所以 JSON 在浏览器中对我来说工作得很好,但我不确定用 Java 创建相同的结构会不会有任何性能问题。
您的 JSON 方法将如何支持多个用户条目?
@NamanGala:请查看更新后的 JSON 示例。
请注意,JSON 总是有一个根元素,它可以是对象
或数组[]
。所以术语Json based
vs Array based
实际上应该是(Json)-Object based
vs. (Json)-Array based
【参考方案1】:
除了上述所有技术差异之外,我认为对象和数组的目的和含义存在根本差异。
-
对象的属性DESCRIBE/DEFINE对象而
数组的元素NOT DESCRIBE/DEFINE数组,相反,数组定义了它的内容。 请注意 - 我不是在谈论技术方面。从技术上讲,您可以有任何组合,但从语义上讲,每个组合都有其用途。
例如持卡人。每张卡都不描述/定义持卡人。但是持卡人确实定义了它只持有卡片的目的/
对象用于表示实体及其属性DESCRIBE/DEFINE实体。以卡片为例。卡片具有颜色、数字等属性,这些属性DESCRIBE/DEFINE 卡片是什么。
对于你上面的例子:
每个代表人的对象由属性 id、firstName 和lastName 定义。
这些人的列表不能是对象的对象,因为每个 id 都没有描述对象的对象。所以
“用户”:[ “身份证”:“身份证”, “key2”:“value2”, “键 3”:“值 3” , “身份证”:“身份证”, “key2”:“value2”, “键 3”:“值 3” ]
是比
更好的表示"users":
"id1":
"id": "id1",
"firstname": "firstname1",
"lastname": "lastname1"
,
"id2":
"id": "id2",
"firstaame": "firstname2",
"lastname": "lastname2"
即使从技术上讲,您也可以使用其中任何一个。 我希望我能够以正确的方式传达(用语言表达)我的想法。
【讨论】:
我能知道为什么投反对票吗?我认为 *** 应该强制对负面投票发表评论,以便人们知道他们的错误是什么。【参考方案2】:这两种方法各有利弊,具体取决于您正在查看的内容。
数组方法易于序列化,并且对“框架”更友好(您可以将 bean 添加到列表中并序列化列表,然后就完成了)。例如,这允许 Web 容器返回响应而无需任何定制。大多数框架都可能开箱即用地支持这一点。
另一方面,基于对象的方法更难生成(相对而言),但在已知键的情况下更容易查找。
因此,为了便于实施(由生产者),请选择基于数组的方法。为了易于使用(由客户使用),请使用基于对象的方法。
【讨论】:
【参考方案3】:您可以使用 object[property]
notation 在 JavaScript 中访问或设置对象中的属性。
在后端使用 array based 方法,并在前端将数组转换为映射(您所指的 JSON based)。
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) 相比,这是一个很小的代价。
如果您主要通过 id 获取后端数据,请在后端使用 基于 JSON 的(您可以使用 LinkedHashMap
来保持顺序)。
【讨论】:
【参考方案4】:您想到的第一个“基于 JSON”的表示法的一大缺点是,某些框架在对其进行(反)序列化时会遇到问题。例如,DataContractSerializer (C# .NET) 将期望字段id1
和id2
在您的对象类users
中定义(硬编码)。我不确定这是否也适用于某些 Java 框架。也许您将使用的框架可以将其反序列化为 HashMap。
总的来说,当涉及到迭代等时,我会发现数组表示法更直观。
【讨论】:
【参考方案5】:这是一个基于总体意见的问题。可能还有很多其他的点,但我可以指出如下。
基于 JSON 的方法:
如果我没记错的话,这将在服务器端使用Map
实现。
优点:在JavaScript中可以直接使用users.id1、users.id2,即不需要迭代
缺点:在客户端,您将需要 JSON 中存在的 id,即硬编码或使用一些动态方法来告诉您 JSON 中存在哪个 id。
基于数组的方法:如果我没记错,那么这将在服务器端使用Array
/List
来实现。
优势:
-
在客户端,您可以直接遍历数组,无需
提前担心其中存在哪个id,即没有硬
编码。
正如 @JBNizet 所指出的,基于数组的方法将保持顺序。
缺点:如果要获取单个 id,则需要遍历数组。
通常我们不会在客户端发送太多信息,因此基于数组的方法不会产生任何问题。如果您想要基于 id 的方法,在双方(服务器和客户端)都可以将数组转换为地图。
【讨论】:
这些都是不错的品脱,但我更关心服务器上发生的事情。 硬编码部分并不是真正的问题。您还可以迭代对象for(key in obj)
,并且可以使键值可配置。但我怀疑这甚至是必要的。
@maja:实际上我不必遍历对象的键。我已经有了钥匙(不是硬编码的)。
正如@JBNizet 所指出的,如果顺序很重要,则需要基于数组的方法。
@maja,在这种情况下,两种方法都是相同的,您在两种情况下都在迭代。【参考方案6】:
在服务器端,数组存储为简单的列表:ArrayList<Content>
,而对象要么存储为映射:HashMap<String, Content>
,要么主要存储为 Java 对象。
为了在 Java 实体与 JSON 之间进行转换,您可以查看 Jackson 项目,它可以为您完成所有这些工作。
我不会担心这两种变体之间的任何性能差异。拥有易于理解的语义 API 更为重要,因此您的决定应基于业务案例而不是性能。
看看你的例子,我认为Array
是更好的方法,因为你想返回一个相同的用户列表。恕我直言,两次发送 id 毫无意义,并且会增加必须传输的数据量。
此外,由于Arrays
在 Java 中存储和迭代要简单得多,因此它们也应该提供比对象更好的性能。
一些一般差异:
数组保持顺序 数组可以包含重复的条目 对象通常具有更大的存储/网络开销 数组的迭代速度更快(在服务器端)【讨论】:
以上是关于对象数组与对象对象的主要内容,如果未能解决你的问题,请参考以下文章