在Java中增长数组的大多数内存有效方法?

Han*_*etz 24 java arrays performance

我不太关心时间效率(操作很少),而是关于内存效率:我可以在没有暂时拥有所有值两次的情况下增长数组吗?

是否有更有效的方法来扩展大型阵列而不是创建新阵列并复制所有值?比如,用一个新的连接它?

将固定大小的数组存储在另一个数组中并重新分配/复制那个顶级数组怎么样?这会留下实际价值吗?

我知道ArrayList,但是我需要很多关于访问数组的控制,并且访问需要非常快.举例来说,我想我更喜欢a[i]al.get(i).

我关心这个问题的主要原因是所讨论的数组(或许多这样的数组)可能很好地占据了主内存的足够大部分,因此在丢弃原始数据之前创建双倍大小的副本的通常策略可能不起作用出.这可能意味着我需要重新考虑整体战略(或我的硬件建议).

jjn*_*guy 29

动态调整大小"数组"或项列表的最佳方法是使用ArrayList.

Java已经在该数据结构中内置了非常有效的大小调整算法.

但是,如果您必须调整自己的阵列,最好使用System.arraycopy()Arrays.copyOf().

Arrays.copyOf() 可以最简单地使用如下:

int[] oldArr;
int newArr = Arrays.copyOf(oldArr, oldArr.length * 2);
Run Code Online (Sandbox Code Playgroud)

这将为您提供一个与旧数组具有相同元素的新数组,但现在可以节省空间.

Arrays一般类有许多用于处理数组伟大的方法.

重要的是要确保每次添加元素时不仅要将数组增加一个元素.最好实施一些策略,您只需每隔一段时间调整一次数组大小. 调整阵列大小是一项昂贵的操作.


Mic*_*rdt 18

是否有更有效的方法来扩展大型阵列而不是创建新阵列并复制所有值?比如,用一个新的连接它?

不.并且可能没有语言,这可以保证在不复制的情况下不断增长阵列.为数组分配空间并执行其他操作后,很可能在数组结束后的内存中有其他对象.那时,根本不可能在不复制阵列的情况下扩展阵列.

将固定大小的数组存储在另一个数组中并重新分配/复制那个顶级数组怎么样?这会留下实际价值吗?

你的意思是有一个数组数组,并将其视为一个由底层数组的串联组成的大数组?是的,那可行("通过间接做伪造"方法),就像在Java中一样,Object[][]只是一个指向Object[]实例的指针数组.

  • 关于"没有语言可以做到这一点"这个主题的真正小调注释...... C将完成这个 - 调整数组大小而不复制数据 - 只要重新分配的内存不会填满整个块和\或没有块位于分配的块之外.使用大块分配器或最快适配分配器时,这并不罕见,具体取决于阵列的大小和对齐方式.有了最合适的分配器,自然的内存将被移动到不同的块的大部分时间,但它仍然消除了"双副本"作为内存可以一次如果实现支持其移动的部分. (13认同)

KLE*_*KLE 6

数组是恒定大小的,因此没有办法增长它们.您只能使用System.arrayCopy复制它们才能高效.


ArrayList完全符合您的需求.除非你投入相当长的时间,否则它的优化程度要比我们任何人都要好得多.它在内部使用System.arrayCopy.


更重要的是,如果你有一些巨大的阶段,你需要列表增长/减少,而其他的不需要增长/减少,你可以在其中进行数千次读取或写入.假设你有一个巨大的性能需求,你认为ArrayList在读/写时太慢了.您仍然可以将ArrayList用于一个巨大的阶段,并将其转换为另一个的数组.请注意,仅当您的应用程序阶段很大时,这才有效.