为什么我在Java中遇到堆空间错误?

问题描述 投票:1回答:2

[我正在尝试编写一个名为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);
        }
    }
}
java
2个回答
4
投票

您一直将已处理元素的副本插入正在读取的同一列表的后面。因此,在处理完原始元素之后,您将开始处理它们的副本,然后再处理其副本的副本,等等。这永远不会停止,并且会导致堆溢出。创建一个新列表,该列表将保留结果并从该方法返回结果,请不要修改当前列表。

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;
}

2
投票

这是因为您的代码将永远不会终止。以下是您的scaleByk函数的流程:

  • 第一个元素为4,j=0,因此会将4个新元素添加到列表中,值为4

  • j=4,但仍小于list.size(),因为在上一步中将大小增加了4。同样,它将触发添加值为4的4个元素。

此循环将一直重复,直到用完分配给程序的堆空间为止。

© www.soinside.com 2019 - 2024. All rights reserved.