对象数组与对象对象

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) 将期望字段id1id2 在您的对象类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 中存储和迭代要简单得多,因此它们也应该提供比对象更好的性能。

一些一般差异:

数组保持顺序 数组可以包含重复的条目 对象通常具有更大的存储/网络开销 数组的迭代速度更快(在服务器端)

【讨论】:

以上是关于对象数组与对象对象的主要内容,如果未能解决你的问题,请参考以下文章

对象数组与对象对象

Javascript 中数组与对象的实例化。数组啥时候是对象,啥时候得到数组的方法?

将对象数组与里面的子对象数组合并

RxSwift 将可观察对象数组与对象数组结合

伪数组与可迭代对象

js中判断对象是不是为数组的几种方式