java循环的奇怪行为

时间:2013-11-08 17:05:53

标签: java loops shuffle

我得到的输出是:

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

3 个答案:

答案 0 :(得分:4)

您的所有PossibleSolution引用相同的ArrayList

(您的所有ArrayList个变量和字段都指向您在ArrayList中创建的单个main()。因此,每次您对列表进行随机播放时,它都会影响到处的列表值。如果您希望PossibleSolution()捕获列表状态的快照,就像调用它时一样,您需要复制。)

答案 1 :(得分:1)

摘要

构造函数不复制Customers,它只存储对它的引用。因此,如果您将对一个对象的引用传递给多个PossibleSolution,那么它们将共享它

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

所有PossibleSolution共享相同的this.OrderedCustomers,因此每当您改变this.OrderedCustomers时,您正在更改所有PossibleSolution的内部

因此,一遍又一遍地打印同样的东西并不令人惊讶

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

答案 2 :(得分:0)

标有&#34;外循环&#34;的所有打印陈述;在所有时间都在同一个数组上执行。退出第一个for循环后,您不再随机化任何内容。你只是一次又一次地打印。