【问题标题】:ArrayList outside while loop isn't being updated未更新while循环外的ArrayList
【发布时间】:2015-05-10 07:01:02
【问题描述】:

无论我尝试什么,我在方法中的ArrayList<int[]> 默认为相同的值。使用System.out.println()s,我发现我的方法中的while 循环对ArrayList 进行了更改,但是一旦退出循环,它总是默认使用数组[0,1,2]

方法如下:

private int[][] computeHighestSum() {
    int totalValue = Integer.MIN_VALUE;
    ArrayList<int[]> lowestPositions = new ArrayList<int[]>(); //creates list to hold sequences
    totalValue = (int) graphTraversal(positions)[0]; //assigns default sequence's value
    lowestPositions.add(positions); //adds default sequence to the List

    Object[] x; 
    //loops through and tries other sequences
    while((x = graphTraversal())[1] != null) {
        //if the current sequence produces greater value, clear the List, and then add this sequence, and assign new value to totalValue
        if((int) x[0] > totalValue) {
            lowestPositions.clear();
            totalValue = (int) x[0];
            lowestPositions.add((int[]) x[1]);

        } else if((int) x[0] == totalValue) { 
            lowestPositions.add((int[]) x[1]);
        }
    }
    return lowestPositions.toArray(new int[lowestPositions.size()][]);
}

该方法所做的最初是遍历一个图形并计算一个总值,并将其设置为默认的totalValue。然后它将特定的图形导航序列添加到ArrayList&lt;int[]&gt;,其中包含int[] 中的导航序列。这将成为默认的totalValue 和图形序列。

然后它使用不同的序列遍历同一个图,直到用完有效序列。如果它发现一个大于当前totalValue 的值,则将该值分配给totalValue,并清除ArrayList,并添加新序列。如果发现相同,则将其添加到ArrayList

while 循环中,它会进行更改和所有操作,但是一旦方法结束,ArrayList 总是包含相同的数组。有趣的是,如果while 循环找到了相同totalValues 的n 数量,它会将它们全部添加到ArrayList 但在方法结束时,@ 内的所有n 元素987654341@ 是同一个数组:[0,1,2]

即使我取出最初的lowestPositions.add(positions);,它在开头添加了[0,1,2],它仍然默认为最后。 totalValue 的计算总是正确的。

如果有帮助,这是我的System.out.println() 调试代码:

 private int[][] computeHighestSum() {
    int totalValue = Integer.MIN_VALUE;
    ArrayList<int[]> lowestPositions = new ArrayList<int[]>();
    totalValue = (int) graphTraversal(positions)[0];
    lowestPositions.add(positions);
    System.out.println("Default Array added: " + Arrays.toString(positions));
    Object[] x;
    while((x = graphTraversal())[1] != null) {
        System.out.println(Arrays.toString((int [])x[1]));
        if((int) x[0] > totalValue) {
            lowestPositions.clear();
            totalValue = (int) x[0];
            lowestPositions.add((int[]) x[1]);
            System.out.println("An Array Greater Added: " + Arrays.toString((int[]) x[1]));
            System.out.println(Arrays.toString(lowestPositions.get(0)));
        } else if((int) x[0] == totalValue) {
            System.out.println("An Array Equal Added: " + Arrays.toString((int[]) x[1]));
            lowestPositions.add((int[]) x[1]);
        }
    }
    System.out.println(Arrays.toString(lowestPositions.get(0)));
    System.out.println(lowestPositions.size());
    System.out.println(totalValue);
    return lowestPositions.toArray(new int[lowestPositions.size()][]);
}

这里是一些示例输出(我现在从终端输入矩阵的值):

【问题讨论】:

  • while((x = graphTraversal())[1] != null) 是什么意思?它不会被编译。
  • @Prashant graphTraversal() 找到下一个有效序列并返回一个数组。该数组的1 索引包含具有序列值的int[]。所以,我将它从调用中获得的数组分配给x,然后检查它是否为空。如果它不为null,则表示它找到了另一个有效序列,则执行while循环,否则它不会寻找另一个序列。
  • 当新序列大于 totalValue 时,您正在执行 lowestPositions.clear();,请检查该部分一次
  • @Arkantos 那是我的意图。如果新序列(它所在的迭代)产生的总值比前一个更大,我想清除列表以便添加新序列,因为前一个序列无效。如果新序列等于前一个序列,则只需将其添加到列表中,而不清除旧序列。
  • @Omoro.. 你为什么认为它不正确? ArrayList 是对象的容器,所以即使int 是原始的,int[] 也是一个对象,所以它仍然有效:)

标签: java loops debugging arraylist while-loop


【解决方案1】:

方法 private int[] getNextPositions() 始终返回对同一个数组的引用: int[] tempArray = positions;

这似乎是问题的根源。

【讨论】:

  • 谢谢!我将其更改为int[] tempArray = positions.clone();,它现在可以正常工作了。那么,从现在开始,当我在方法中引用实例变量时,为了安全起见,我应该引用克隆来代替?
  • 这取决于你用实例变量做什么。使用不可变对象通常更安全,但复制所有内容都是有代价的。有时它可能效率不高。一般来说,如果要从方法中返回值,返回对对象字段的引用是有风险的,最好复制一份。
猜你喜欢
  • 1970-01-01
  • 2023-03-04
  • 2012-11-06
  • 2020-07-17
  • 2018-08-17
  • 2017-05-21
  • 1970-01-01
  • 1970-01-01
  • 2019-03-11
相关资源
最近更新 更多