繁体   English   中英

为什么在一个 ArrayList 中改变一个对象会在所有其他 ArrayList 中改变它?

[英]Why does mutating an object in one ArrayList change it in all other ArrayLists?

我正在制作一个 cpu 调度模拟器(用于学校项目)。 我的roundRobin函数有问题。 当我做c.get(i).jobTime -= 2; c.get(i).jobTime -= 1; 它影响我的其他ArrayList s,所以我不能做我的其他功能。 在我调用roundRobin2之前,我的列表完全正常。 为什么会发生这种情况?

例如,这是我的list4roundRobin2之后的roundRobin2

list 4: [Job101 0, Job102 0, Job103 0, Job104 0, Job105 0, Job106 0]

这就是我读入文件的方式,并将Jobs对象放入我的ArrayList

Scanner input = new Scanner(new File("testdata1.txt"));
ArrayList<Jobs> list = new ArrayList<Jobs>();
ArrayList<Jobs> list2 = new ArrayList<Jobs>();
ArrayList<Jobs> list3 = new ArrayList<Jobs>();
ArrayList<Jobs> list4 = new ArrayList<Jobs>();

Jobs first;

while (input.hasNext()) {
    first = new Jobs(input.next(), input.nextInt());
    list.add(first);
    list2.add(first);
    list3.add(first);
    list4.add(first);
}

input.close();

这是我的roundRobin2

public void roundRobin2(ArrayList<Jobs> c, int sT) {
    int size = c.size();
    int cT = 0;
    int ccT = 0;
    while (!c.isEmpty()) {
        int i = 0;
        System.out.println(c);
        for (i = 0; i < size; i++) {
            if ((c.get(i).jobTime) >= 2) {
                c.get(i).jobTime -= 2;
                cT += 2;

                if ((c.get(i).jobTime) == 0) {
                    ccT += cT;
                }
            } else {
                (c.get(i).jobTime) -= 1;
                cT += 1;

                if ((c.get(i).jobTime) == 0) {
                    ccT += cT;
                }
            }
        }
        for (i = 0; i < size; i++) {
            if ((c.get(i).jobTime) == 0) {
                c.remove(i);
                size = c.size();
            }
        }
    }
    System.out.println("\nAverage completion times: "+ccT+"/"+sT+" = "+((ccT)/sT));
}

在每次迭代中,您只创建一个对象并将其添加到所有 4 个列表中。 当你改变那个对象时,你,好吧,改变它。 该变化将反映在所有列表中,因为它们都存储相同的对象引用。

while (input.hasNext()) {
    first = new Jobs(input.next(), input.nextInt());
    list.add(first);
    list2.add(first);
    list3.add(first);
    list4.add(first);
}

相反,您需要为每个列表添加一个新的对象引用(如果您希望将对象的副本存储在每个列表中)。

while (input.hasNext()) {
    String s = input.next();
    int i = input.nextInt();
    list.add(new Jobs(s, i));
    list2.add(new Jobs(s, i));
    list3.add(new Jobs(s, i));
    list4.add(new Jobs(s, i));
}

在第一个代码示例中, list.get(n) == list2.get(n)将为true (对于任何有效的n和 4 中的任何两个列表都为true )。 在第二个示例中,它将是false因为您现在拥有完全不相关的对象,这些对象恰好在将它们添加到列表时存储了相同的值。

虽然与您的问题没有直接关系,但您可能希望阅读此处指出的一些答案,以便更好地理解“错误”的性质。

Java是“通过引用传递”还是“传递价值”?

它不是一个真正的bug,它是一个Java内在属性:)

祝好运

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM