【问题标题】:Weird behaviour with java loops [closed]java循环的奇怪行为[关闭]
【发布时间】:2013-11-08 17:05:52
【问题描述】:

我得到的输出是:

Inside loop : [5, 6, 3, 1, 4, 2]

Inside loop : [3, 1, 5, 6, 4, 2]

Inside loop : [1, 2, 4, 5, 6, 3]

Inside loop : [5, 2, 6, 4, 3, 1]

Outside loop : [5, 2, 6, 4, 3, 1]

Outside loop : [5, 2, 6, 4, 3, 1]

Outside loop : [5, 2, 6, 4, 3, 1]

Outside loop : [5, 2, 6, 4, 3, 1]

代码:

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

public class PossibleSolution {
    // the indices of where to place the cuts to delimit routes (different
    // vehicles)
    int[] indicesCut;
    // the set of ordered Customers for each route. Routes delimited by cuts
    ArrayList<Integer> OrderedCustomers;
    // length of array
    int size;

    // Constructor
    public PossibleSolution(int[] indices, ArrayList<Integer> Customers) {
        this.indicesCut = indices;
        this.OrderedCustomers = Customers;

        this.size = Customers.size();
    }

    // method to generate the neighborhood for one possible solution. We need a
    // parameter
    // to specify the number of neighbors to generate

    public PossibleSolution[] generateNeighborhood(int number) {
        PossibleSolution[] sol = new PossibleSolution[number];
        for (int i = 0; i < number; i++) {
            java.util.Collections.shuffle(this.OrderedCustomers);

            sol[i] = new PossibleSolution(this.indicesCut, this.OrderedCustomers);
            System.out.println("Inside loop : " + sol[i].OrderedCustomers);
        }

        for (int i = 0; i < number; i++) {
            System.out.println("Outside loop : " + sol[i].OrderedCustomers);
        }

        return sol;
    }

    public static void main(String[] args) {
        ArrayList<Integer> Customers = new ArrayList();
        Customers.add(2);
        Customers.add(4);
        Customers.add(5);
        Customers.add(1);
        Customers.add(6);
        Customers.add(3);
        int[] ind = { 2, 3 };
        PossibleSolution initialSol = new PossibleSolution(ind, Customers);
        PossibleSolution[] table = initialSol.generateNeighborhood(4);
    }
}

【问题讨论】:

  • 问题是什么?代码应该做什么?你能解释一下你对输出的期望吗?

标签: java loops shuffle


【解决方案1】:

您所有的PossibleSolutions 都引用同一个ArrayList

(您的所有ArrayList 变量和字段都指向您在main() 中创建的单个ArrayList。因此,每次对列表进行洗牌时,它都会影响列表中的所有值。如果您想要@987654326 @ 要捕获调用时列表状态的快照,您需要进行复制。)

【讨论】:

  • 要扩展,OP 需要在他的 PossibleSolution 构造函数中使用 .clone() 或 Collections.copy 方法,以便它们引用不同的数据结构。
【解决方案2】:

总结

构造函数不复制客户,它只是存储对它的引用。因此,如果您将对一个对象的引用传递给多个PossibleSolutions,那么他们都会共享它

public PossibleSolution(int[]indices, ArrayList<Integer> Customers){
    this.indicesCut = indices;
    this.OrderedCustomers = Customers; //<-- Only the reference is copied, not the object

    this.size = Customers.size();
}

说明

for(int i =0; i<number;i++){        
        java.util.Collections.shuffle(this.OrderedCustomers);

        sol[i] = new PossibleSolution(this.indicesCut,this.OrderedCustomers);
        System.out.println("Inside loop : "+sol[i].OrderedCustomers);
    }

所有PossibleSolutions 共享相同的this.OrderedCustomers,因此,每当您改组this.OrderedCustomers 时,您都在更改所有PossibleSolutions 的内部结构

所以它一遍又一遍地打印同样的东西并不奇怪

for(int i=0; i<number;i++){
   System.out.println("Outside loop : "+sol[i].OrderedCustomers);
}

因为它相同 OrderedCustomers

解决方案

如果你想要一个副本,那么你需要请求一个对象的副本,而不仅仅是引用,最简单的方法是使用System.arrayCopy

System.arraycopy(from, 0,to,0,from.length);

进一步阅读

可以在here找到同样的“在不同地方引用同一对象”问题的简化版本


其他说明

OrderedCustomersCustomers 都是变量,因此它们应该是 lowerCamelCase; orderedCustomerscustomers

【讨论】:

    【解决方案3】:

    所有标记为“外部循环”的打印语句始终在同一个数组上执行。退出第一个 for 循环后,您不再随机化任何东西。您只是一次又一次地打印。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-02-11
      相关资源
      最近更新 更多