【问题标题】:Alternative data structure for a multidimensional array多维数组的替代数据结构
【发布时间】:2011-08-23 17:49:57
【问题描述】:

我有一个简单的问题,我正在开展一个项目,该项目需要一个具有 id 和 x、y 坐标的对象。这一切都存储在一个对象中,其想法是将其放置在一个二维数组中。但是,可能会创建和存储大量对象,并且数组的大小可能很大。在存储数据的大小和速度上是否有更有效的方法?我阅读了有关使用地图的信息,这可能是我最好的选择。

【问题讨论】:

    标签: java arrays multidimensional-array performance 2d


    【解决方案1】:

    答案取决于您的应用程序的主要访问模式是什么。

    如果主要访问模式是在特定的 x,y 坐标处查找对象,那么最好使用以下方法之一:

    • 一个 2D 数组(如您目前所拥有的);即Thing[][],
    • Map<Point, Thing>,或
    • Map<Integer, Map<Integer, Thing>>

    (我建议第三种选择,因为第二种选择可能会导致在您每次查找数据结构时创建一个临时的Point 对象。还有其他方法可以解决这个问题,但它使应用程序更复杂。)

    如果 2D 数组是稀疏填充的,那么 Map 方法将以时间为代价节省空间。如果数组密集填充,则 Map 方法可能比二维数组使用 更多 空间。

    如果主要访问模式是在给定的 x,y 坐标附近(或在一个区域中)寻找对象,那么您可能需要类似四叉树数据结构的东西。

    最后要注意的一点是,使用标准集合类型存在不可避免的开销,尤其是当一个或多个参数类型是原始类型时。
    如果您的性能要求特别“硬”,那么手动设计和实现自定义数据结构将节省空间和时间……如果您做得对。但缺点是要编写、测试和维护的代码要多得多,而且自定义数据结构与标准集合 API 不兼容。

    【讨论】:

    • 主要访问模式将是 x、y 坐标。需要在速度和空间之间取得平衡。目前我用大量数据进行了测试,这很有可能发生。使用 2D 数组,我不得不增加 Java 堆大小,并且读取大约需要 6 分钟,所以我将同时查看 map 和四叉树。
    • @Stephen,我基本同意。但是,如果索引高于 128,使用 Integers 仍会创建新的 Integers。然后您将创建 2 个新对象而不是 1 个新 Point 对象。无论如何,Java GC 对生命周期很短的对象进行了大量优化,比如在这种情况下,Pint 键就是这样。所以可能选项 2 或选项 3 之间的选择主要是偏好。
    【解决方案2】:
    Map<Double, java.awt.Point>
    

    java.awt.Point 可以工作,或者您可以创建自己的数据类型来保存 x、y 坐标。

    这将使您快速查找,但使用比直接数组更多的内存(不确定更多,可能不会太糟糕)。

    另一种选择是将这三个东西(ID、x、y)结合起来并将它们存储在一个数组中,然后使用Arrays.binarySearch 来获取它们。它需要对数组进行排序。

    编辑:

    如果你想从 x, y 映射到你会做的双精度:

    Map<java.awt.Point, Double>
    

    【讨论】:

    • id 将是 double 类型。 id 将是 1 到 2d 数组中“单元”的数量。我主要是搜索 x 和 y 数字以及一些更少的 id,所以我不知道我是否可以使用二进制搜索。谢谢我检查使用地图。
    • 我认为地图类型是错误的。 OP 需要从坐标映射到 Double(或 String),而不是相反。
    • 考虑一下,考虑到浮点的性质,我认为将 Double 作为键是行不通的……对吧?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多