[我正在尝试编写一个名为scaleByK的方法,该方法将整数ArrayList作为参数,并用自身的k个副本替换值k的每个整数。例如,如果列表在调用方法之前存储了值[4,1,2,0,3],则它应存储值[4,4,4,4,1,2,2,3,3, 3]在方法完成执行之后。零和负数应通过此方法从列表中删除。问题是我遇到了Java堆空间错误。
public class Lab1construct2 {
public static void main(String[] args) {
ArrayList<Integer> list = new ArrayList<>();
list.add(4);
list.add(1);
list.add(2);
list.add(0);
list.add(3);
Lab1construct2 myprogram = new Lab1construct2();
myprogram.scalebyk(list);
System.out.print(list);
}
public void scalebyk(ArrayList<Integer> list) {
int j = 0;
while( j < list.size()) {
int elm =list.get(j);
for(int i=1; i<=elm; i++) {
list.add(elm);
}
j = j + list.get(j);
}
}
}
您一直将已处理元素的副本插入正在读取的同一列表的后面。因此,在处理完原始元素之后,您将开始处理它们的副本,然后再处理其副本的副本,等等。这永远不会停止,并且会导致堆溢出。创建一个新列表,该列表将保留结果并从该方法返回结果,请不要修改当前列表。
public List<Integer> scalebyk(ArrayList<Integer> list) {
List<Integer> result = new ArrayList<Integer>();
for (Integer element : list) {
for (int i = 0; i < element; i++) {
result.add(element);
}
}
return result;
}
这是因为您的代码将永远不会终止。以下是您的scaleByk函数的流程:
第一个元素为4,j=0
,因此会将4个新元素添加到列表中,值为4
j=4
,但仍小于list.size()
,因为在上一步中将大小增加了4。同样,它将触发添加值为4的4个元素。
此循环将一直重复,直到用完分配给程序的堆空间为止。