【问题标题】: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

标签: java arrays json performance maintainability


【解决方案1】:

除了上述所有技术差异之外,我认为对象和数组的目的和含义存在根本差异。

  1. 对象的属性DESCRIBE/DEFINE对象而
  2. 数组的元素NOT DESCRIBE/DEFINE数组,相反,数组定义了它的内容。 请注意 - 我不是在谈论技术方面。从技术上讲,您可以有任何组合,但从语义上讲,每个组合都有其用途。

    • 例如持卡人。每张卡都不描述/定义持卡人。但是持卡人确实定义了它只持有卡片的目的/

    • 对象用于表示实体及其属性DESCRIBE/DEFINE实体。以卡片为例。卡片具有颜色、数字等属性,这些属性DESCRIBE/DEFINE 卡片是什么。

对于你上面的例子:

  1. 每个代表人的对象由属性 id、firstName 和lastName 定义。

  2. 这些人的列表不能是对象的对象,因为每个 id 都没有描述对象的对象。所以

    “用户”:[ { “身份证”:“身份证”, “key2”:“value2”, “键 3”:“值 3” }, { “身份证”:“身份证”, “key2”:“value2”, “键 3”:“值 3” } ]

是比

更好的表示
"users": {
    "id1": {
        "id": "id1",
        "firstname": "firstname1",
        "lastname": "lastname1"
    },
    "id2": {
        "id": "id2",
        "firstaame": "firstname2",
        "lastname": "lastname2"
    }
}

即使从技术上讲,您也可以使用其中任何一个。 我希望我能够以正确的方式传达(用语言表达)我的想法。

【讨论】:

  • 我能知道为什么投反对票吗?我认为 stackoverflow 应该强制对负面投票发表评论,以便人们知道他们的错误是什么。
【解决方案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 来实现。

        优势:

        1. 在客户端,您可以直接遍历数组,无需 提前担心其中存在哪个id,即没有硬 编码。
        2. 正如 @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 中存储和迭代要简单得多,因此它们也应该提供比对象更好的性能。

        一些一般差异:

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

        【讨论】:

          猜你喜欢
          • 2015-11-13
          • 1970-01-01
          • 2014-09-13
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-03-18
          相关资源
          最近更新 更多