对象数组与对象对象
Array of objects vs Object of Objects
问题是决定以下符号之间的权衡:
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 post,我决定(在前端)使用 JSON 对象符号而不是对象数组,因为它符合我的要求更好的性能和更少的浏览器代码。
但问题是列表本身不是静态的。我的意思是列表正在生成,即从 DB (NoSQL) 生成 fetched/stored,并通过服务器上的 Java API 为新条目创建。我无法决定我应该在后端使用哪种表示法(最终也会影响 UI )。
任何 thoughts/suggestion 关于性能、可维护性或可伸缩性的信息都将受到赞赏。
这是一个完全基于意见的问题。可能还有很多其他的要点,但我可以指出如下。
JSON 基于方法:
如果我没记错的话,这将在服务器端使用 Map
来实现。
优点:在JavaScript中可以直接使用users.id1,users.id2即不需要迭代
缺点: 在客户端,您将如何要求 JSON 中存在的 ID,即硬编码或使用一些动态方法来告诉您您的 JSON.
中存在哪个 ID
基于数组的方法: 如果我没记错,那么这将在服务器端使用 Array
/List
实现。
优点:
- 客户端可以直接遍历数组,不用
提前担心其中存在哪个 id 即不难
编码。
- 正如 @JBNizet 所指出的,基于数组的方法将保持顺序。
缺点:如果要获取单个 id,则需要遍历数组。
通常我们不会在客户端发送太多信息,因此基于数组的方法不会产生任何问题。并且 如果您想要基于 id 的方法,则在双方(服务器和客户端)都可以将数组转换为映射。
在服务器端,数组存储为简单的列表:ArrayList<Content>
,而对象要么存储为映射:HashMap<String, Content>
,要么主要存储为 Java 个对象。
为了将 Java 实体与 JSON 相互转换,您可以查看 Jackson 项目,它为您完成了所有这些工作。
我不担心这两个变体之间的任何性能差异。更重要的是具有可理解的语义 API,因此您应该根据业务案例而不是性能来做出决定。
看看你的例子,我认为 Array
是更好的方法,因为你想要 return 一个全部平等的用户列表。两次发送 id 毫无意义,并且会增加必须传输的数据量。
此外,由于 Arrays
在 Java 中更易于存储和迭代,因此它们也应该提供比对象更好的性能。
一些一般差异:
- 数组保持顺序
- 数组可以包含重复条目
- 对象通常有更大的storage/network开销
- 数组迭代速度更快(在服务器端)
您想到的第一个 "JSON based" 表示法的一大缺点是某些框架在(反)序列化方面会有问题。例如,DataContractSerializer (C# .NET) 将期望字段 id1
和 id2
在对象 users
的 class 中定义(硬编码)。我不确定这是否也适用于某些 Java 框架。也许您将使用的框架可以将其反序列化为 HashMap。
总而言之,我发现在迭代等方面使用数组表示法更直观。
您可以使用 object[property]
notation 访问或设置 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) 相比,这是一个很小的代价。
如果您主要在后端对您的数据进行 get by id,请在后端本身使用 JSON Based(您可以使用 LinkedHashMap
以保持顺序)。
这两种方法各有利弊,具体取决于您所关注的是什么。
数组方法易于序列化并且更 'framework' 友好(您可以将 bean 添加到列表并序列化列表,然后就完成了)。例如,这允许 Web 容器 return 响应而无需任何自定义。大多数框架可能开箱即用地支持这一点。
另一方面,基于对象的方法更难生成(相对而言),但如果密钥已知,则更容易查找。
因此,为了便于实施(由生产者),请选择基于数组的方法。为了易于使用(由客户使用),请使用基于对象的方法。
除了上述所有技术差异外,我认为对象和数组的用途和含义也存在根本差异。
- 对象的属性DESCRIBE/DEFINE对象而
数组的元素不是DESCRIBE/DEFINE数组,相反,数组定义了它的内容。
请注意 - 我不是在谈论技术方面。您可以在技术上有任何组合,但在语义上每个组合都有其目的。
比如名片夹。每张卡 不是 DESCRIBE/DEFINE 持卡人。但是持卡人确实定义了它只持有卡片的目的/
一个对象用来表示一个实体及其属性DESCRIBE/DEFINE实体。以卡片为例。卡片具有颜色、数字等属性,DESCRIBE/DEFINE 卡片是什么。
对于你上面的例子:
代表一个人的每个对象 由属性 id、firstName 和 lastName 定义。
这些人的列表不能是objects of objects因为每个id都没有描述objects of objects。所以
"users":[
{
"id":"id",
"key2":"value2",
"key3":"value3"
},
{
"id":"id",
"key2":"value2",
"key3":"value3"
}
]
比
更好
"users": {
"id1": {
"id": "id1",
"firstname": "firstname1",
"lastname": "lastname1"
},
"id2": {
"id": "id2",
"firstaame": "firstname2",
"lastname": "lastname2"
}
}
尽管从技术上讲您可以使用其中任何一种。
我希望我能够以正确的方式传达(表达)我的想法。
问题是决定以下符号之间的权衡:
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 post,我决定(在前端)使用 JSON 对象符号而不是对象数组,因为它符合我的要求更好的性能和更少的浏览器代码。
但问题是列表本身不是静态的。我的意思是列表正在生成,即从 DB (NoSQL) 生成 fetched/stored,并通过服务器上的 Java API 为新条目创建。我无法决定我应该在后端使用哪种表示法(最终也会影响 UI )。
任何 thoughts/suggestion 关于性能、可维护性或可伸缩性的信息都将受到赞赏。
这是一个完全基于意见的问题。可能还有很多其他的要点,但我可以指出如下。
JSON 基于方法:
如果我没记错的话,这将在服务器端使用 Map
来实现。
优点:在JavaScript中可以直接使用users.id1,users.id2即不需要迭代
缺点: 在客户端,您将如何要求 JSON 中存在的 ID,即硬编码或使用一些动态方法来告诉您您的 JSON.
中存在哪个 ID基于数组的方法: 如果我没记错,那么这将在服务器端使用 Array
/List
实现。
优点:
- 客户端可以直接遍历数组,不用 提前担心其中存在哪个 id 即不难 编码。
- 正如 @JBNizet 所指出的,基于数组的方法将保持顺序。
缺点:如果要获取单个 id,则需要遍历数组。
通常我们不会在客户端发送太多信息,因此基于数组的方法不会产生任何问题。并且 如果您想要基于 id 的方法,则在双方(服务器和客户端)都可以将数组转换为映射。
在服务器端,数组存储为简单的列表:ArrayList<Content>
,而对象要么存储为映射:HashMap<String, Content>
,要么主要存储为 Java 个对象。
为了将 Java 实体与 JSON 相互转换,您可以查看 Jackson 项目,它为您完成了所有这些工作。
我不担心这两个变体之间的任何性能差异。更重要的是具有可理解的语义 API,因此您应该根据业务案例而不是性能来做出决定。
看看你的例子,我认为 Array
是更好的方法,因为你想要 return 一个全部平等的用户列表。两次发送 id 毫无意义,并且会增加必须传输的数据量。
此外,由于 Arrays
在 Java 中更易于存储和迭代,因此它们也应该提供比对象更好的性能。
一些一般差异:
- 数组保持顺序
- 数组可以包含重复条目
- 对象通常有更大的storage/network开销
- 数组迭代速度更快(在服务器端)
您想到的第一个 "JSON based" 表示法的一大缺点是某些框架在(反)序列化方面会有问题。例如,DataContractSerializer (C# .NET) 将期望字段 id1
和 id2
在对象 users
的 class 中定义(硬编码)。我不确定这是否也适用于某些 Java 框架。也许您将使用的框架可以将其反序列化为 HashMap。
总而言之,我发现在迭代等方面使用数组表示法更直观。
您可以使用 object[property]
notation 访问或设置 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) 相比,这是一个很小的代价。
如果您主要在后端对您的数据进行 get by id,请在后端本身使用 JSON Based(您可以使用 LinkedHashMap
以保持顺序)。
这两种方法各有利弊,具体取决于您所关注的是什么。
数组方法易于序列化并且更 'framework' 友好(您可以将 bean 添加到列表并序列化列表,然后就完成了)。例如,这允许 Web 容器 return 响应而无需任何自定义。大多数框架可能开箱即用地支持这一点。
另一方面,基于对象的方法更难生成(相对而言),但如果密钥已知,则更容易查找。
因此,为了便于实施(由生产者),请选择基于数组的方法。为了易于使用(由客户使用),请使用基于对象的方法。
除了上述所有技术差异外,我认为对象和数组的用途和含义也存在根本差异。
- 对象的属性DESCRIBE/DEFINE对象而
数组的元素不是DESCRIBE/DEFINE数组,相反,数组定义了它的内容。 请注意 - 我不是在谈论技术方面。您可以在技术上有任何组合,但在语义上每个组合都有其目的。
比如名片夹。每张卡 不是 DESCRIBE/DEFINE 持卡人。但是持卡人确实定义了它只持有卡片的目的/
一个对象用来表示一个实体及其属性DESCRIBE/DEFINE实体。以卡片为例。卡片具有颜色、数字等属性,DESCRIBE/DEFINE 卡片是什么。
对于你上面的例子:
代表一个人的每个对象 由属性 id、firstName 和 lastName 定义。
这些人的列表不能是objects of objects因为每个id都没有描述objects of objects。所以
"users":[ { "id":"id", "key2":"value2", "key3":"value3" }, { "id":"id", "key2":"value2", "key3":"value3" } ]
比
更好"users": {
"id1": {
"id": "id1",
"firstname": "firstname1",
"lastname": "lastname1"
},
"id2": {
"id": "id2",
"firstaame": "firstname2",
"lastname": "lastname2"
}
}
尽管从技术上讲您可以使用其中任何一种。 我希望我能够以正确的方式传达(表达)我的想法。