如何获取字符串 2D 数组的子数组(例如减少前 1000 行)?



>我有一个巨大的二维字符串数组。我想从 1000D 数组中读取前 200 行,并将元素复制到其他几个 2D 数组中,并将原始数组减少 1000 行以节省内存。我尝试了类似以下代码的内容:

public static String[][] getSubArray(String[][] origArray, int offset) {
String[][] tempArray = new String[origArray.length - offset][];
System.arraycopy(origArray, offset, tempArray, 0, tempArray.length);
return tempArray;
}

但这没有按预期工作,我得到了错误的数组。

第一点,它Java中的数组是一个Object.当您初始化新数组(即String[][] arr = new String[10_000][10_000]( 这意味着,您在内存中有连续区域来容纳所有10_000 x 10_000字符串元素,并将arr引用到此Object。无法减小数组的大小。例如ArrayList通过创建新的对象和重写引用arr来增加内部数组大小。

因此,您希望从数组中获取 1000 个元素并减少现有数组以节省内存。通过这些步骤,这意味着:

  1. 创建新的 2D 数组 1 以保存 1000 个元素;
  2. 将原始数组中的 1000 个元素复制到新数组 1 中;
  3. 创建新的 2D 数组 2 以保存原始数组的其余元素;
  4. 将 rest 元素复制到新数组 2 中;
  5. 将引用arr更改为数组 2。

原始数组可用于 GC,但它仍然存在(因为 GC 永远无法启动(。无论如何,由于您认为要做的事情,将增加内存使用量。

我提议避免所有这些数组副本。 例如,你有巨大的 2D 数组。不要修改此数组。让它作为一个数组在内存中。您拥有所需的所有数据。只需向方法添加偏移量,并让它们准备好原始数组中的数据。

此外,Java中的 2D 数组是数组数组。这意味着,您可以获取对所需行的引用,而无需将其复制到新数组。例:

String[][] originalArray = new String[2][2];
String[] row_0 = originalArray[0];
String[] row_1 = originalArray[1];

附言当然,如果你必须在 REST 中或从当前的 JVM 中发送这个数组,那么你肯定必须创建所需部分的副本,但你仍然不必更改原始数组。

例:

public static void main(String... args) {
String[][] origArray = {
{ "1.1", "1.2", "1.3", "1.4", "1.5" },
{ "2.1", "2.2", "2.3", "2.4", "2.5" },
{ "3.1", "3.2", "3.3", "3.4", "3.5" },
{ "4.1", "4.2", "4.3", "4.4", "4.5" },
{ "5.1", "5.2", "5.3", "5.4", "5.5" } };
int offs = 0;
final int rows = 2;
while (offs < origArray.length) {
doSomething(origArray, offs, rows);
offs += rows;
System.out.println("---");
}
originalArray = null;  // make it available for GC
}
public static void doSomething(String[][] origArray, int offs, int rows) {
for (int row = offs; row < origArray.length && row < offs + rows; row++)
doSomethingWithArray(origArray[row], row);
}
public static void doSomethingWithArray(String[] arr, int row) {
// here you have a reference to row from originalArray (without copying it to the new array) 
System.out.println(Arrays.toString(arr));
}

输出:

[1.1, 1.2, 1.3, 1.4, 1.5]
[2.1, 2.2, 2.3, 2.4, 2.5]
---
[3.1, 3.2, 3.3, 3.4, 3.5]
[4.1, 4.2, 4.3, 4.4, 4.5]
---
[5.1, 5.2, 5.3, 5.4, 5.5]
---

如您所见,我用 3 次迭代 2 行doSomething。并且没有任何类似的数组拷贝或 smth。

附言毕竟,不要忘记清除对庞大数组的所有引用,使其可用于GC。

相关内容