有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

将新数组分配给现有数组以在Java中“清除”该数组是否是一种不好的做法?

因此,我目前正在开发一个程序,该程序需要能够处理存储在数组中的大量数据,并且需要一种方法来清除数组中的所有数据。对于下面的例子,在内存方面这样做会是一件坏事吗?我知道垃圾收集器最终会为您清理它,但有没有其他方法(例如for循环并将其中的每个值设置为null)比这更好的原因

Object[] objArray = new Object[n];
/*Do some stuff with objArray*/
objArray = new Object[n]

否则,这样做将允许此操作以O(1)时间运行,而for循环则需要O(n)时间


共 (6) 个答案

  1. # 1 楼答案

    从技术上讲,这真的不重要

    它更多的是关于可读性和意图的传达

    你看,现在你努力使你的对象不可变。如果无法更改,则可以避免各种多线程问题。因此,更新指向新数组的引用与此不完全一致

    另一点值得一提的是:如果您真的想清除数组(至少对于基本类型),那么最好迭代数组并重置其所有插槽。(显然,对于引用类型的数组,这是不可能的)

  2. # 2 楼答案

    ByteBuffer使用的另一种方法是保留原始数组,保留其内容,并从头开始覆盖。使用数组时,使用最后更新的元素的索引以避免数组的其余部分。“清除”数组并不会真正获得任何东西,除非处理数组的任何东西都在寻找某个特定的值来指示内容的结束

  3. # 3 楼答案

    这很好,因为您使用的是“primitive”数组,而不是任何集合。您可能会对上一个数组的内存分配感到不安全,但不要担心GC会帮您解决这个问题。但在使用Collections API时,您宁愿调用:

    yourCollection.clear()
    
  4. # 4 楼答案

    这是坏习惯

    首先,为变量分配一个新数组实际上并没有“清除”任何内容(下面将对此进行详细介绍)

    这是最佳做法:

    objArray = null;
    

    这使得原始数组无法访问,因此它将(最终)被垃圾收集

    它还可以避免不必要的内存分配,从而创建用于替换旧阵列的空阵列

    但是,这两个选项都不会“清除”原始阵列,这可能会造成安全风险,尽管风险很小。在垃圾被收集之前,如果内存内容被转储,数组的内容可能是可预测的

    真正清除阵列的方法是:

    Arrays.fill(objArray, null);
    
  5. # 5 楼答案

    不,这不是坏习惯。然而,将数组的所有索引置零很可能会更快(从技术上讲,这就是所谓的实现细节;但是可以在您的特定系统上对其进行基准测试),因为不需要额外的分配新内存的步骤。但是,请注意不要成为所谓的过早优化的受害者,因为如果您以后发现需要进行重大更改,这可能会导致您浪费时间。另外,请注意,由于您将继续使用现有的数组对象,因此代码中引用它的任何其他部分也将看到对它的更改

  6. # 6 楼答案

    典型的Java用户不应该担心内存管理,除非安全性或性能是明显的瓶颈。见relatedquestions

    如果您确实需要为逻辑“擦除”阵列(即将阵列标记为重置),并且由于您打算稍后重用阵列,您可以

    • 使用布尔值将数组标记为“不可用”,直到再次填充为止(如果数组中的对象不消耗太多内存,则更好的解决方案)

    • null填充它,而不是将null分配给它,以避免在长期内多次分配数组(特别是当n较大时): Arrays.fill(objArray, null);