我需要地图转换成二维数组,所以我写了这段代码,但它吃大量的内存,我想不通为什么。转换集合数组没有额外的内存
private DataItem[][] convertDataToArrays(boolean[] filter,
Map<Integer, List<T>> dataSet)
double[] data = new double[sizeOfNewVector];
DataItem[][] reducedData = new DataItem[dataSet.size()][];
for (int i = dataSet.size() - 1; i >= 0; i--) {
reducedData[i] = new DataItem[dataSet.get(i).size()];
for (int j = reducedData[i].length - 1; j >= 0; j--) {
reducedData[i][(reducedData[i].length - 1) - j] = new DataItem(data);
dataSet.get(i).remove(j);
}
dataSet.remove(i);
}
return reducedData;
这里的DataItem类:
public class DataItem {
public double[] data;
public DataItem(double[] data) {
this.data = new double[data.length];
System.arraycopy(data, 0, this.data, 0, data.length);
}
}
算法应该做的:
- 采取最后一个元素从列表
- 复制。
- 从列表中删除元素
- 店复制到新的二维数组
- 重复,直到列表为空
这应该在地图中的所有名单。
问题是,步骤3见好就收元素,且不收缩阵列,所以当我插入转换方法,一个巨大的数据集,我有java.lang.OutOfMemoryError:GC开销超过限制
我需要这样做,没有任何额外的内存。任何人都可以帮助我吗?
编辑:
我正在使用ArrayList和HashMap。
为什么你需要复制'DataItem'对象,如果你删除原件?只需将引用复制到结果数组中即可。请指定你的情况下'dataSet'有多大(大概有多少''DataItem'对象总共有)。 –
我已经删除了一个修改“数据”的内部循环。它可以是更短的矢量。这对我的问题并不重要,我不想在这里混淆人。 –
您将永远需要*一些*额外的存储空间。我不知道,你用于'Map'和'List'的哪个集合,但是*每个*类型都会在某个时候缩小尺寸(尽管不是立即)。 'HashMap'和'ArrayList'可能会比我们说的'TreeMap'和'LinkedList'花费更长的时间,但是改变'LinkedList'具有相当大的内存开销。我认为你的问题确实在于你的工作非常非常接近内存限制。如果你不能在这里支付这个开销并以某种方式逃避,它会把你咬到别的地方。 – mastov