Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/335.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/flash/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
java.util.ConcurrentModificationException由于意外修改_Java - Fatal编程技术网

java.util.ConcurrentModificationException由于意外修改

java.util.ConcurrentModificationException由于意外修改,java,Java,我正在实施A*算法,将给定数量的出租车分配给给定数量的客户: public SearchNode AStarSearch(List<Car> allCars, List<Customer> allCustomers) { // creates first node SearchNode firstNode = createFirstNode(allCars, allCustomers); open.add(firstNode); Sea

我正在实施A*算法,将给定数量的出租车分配给给定数量的客户:

public SearchNode AStarSearch(List<Car> allCars, List<Customer> allCustomers) {

    // creates first node
    SearchNode firstNode = createFirstNode(allCars, allCustomers);
    open.add(firstNode);

    SearchNode currentNode;

    while(true) {
        currentNode = open.poll();   //error thrown here
        if (currentNode.allCustomers.isEmpty()) break;

        closed.add(currentNode);

        SearchNode temp;

        Iterator<Customer> itrCus = currentNode.allCustomers.iterator();
        Iterator<Car> itrCar = currentNode.allCars.iterator();

        while (itrCus.hasNext()) {
            Customer currentCustomer = itrCus.next();
            while (itrCar.hasNext()) {
                Car currentCar = itrCar.next();
                temp = new SearchNode(currentNode, currentCar, currentCustomer);
                openUpdate(currentNode, temp);
            }
        }
    }
    return currentNode;
}
公共搜索节点AStarSearch(列出所有汽车,列出所有客户){
//创建第一个节点
SearchNode firstNode=createFirstNode(所有汽车、所有客户);
open.add(firstNode);
SearchNode当前节点;
while(true){
currentNode=open.poll();//此处抛出错误
如果(currentNode.allCustomers.isEmpty())中断;
closed.add(当前节点);
搜索节点温度;
迭代器itrCus=currentNode.allCustomers.Iterator();
迭代器itrCar=currentNode.allCars.Iterator();
while(itrCus.hasNext()){
Customer currentCustomer=itrCus.next();
while(itrCar.hasNext()){
Car currentCar=itrCar.next();
temp=新搜索节点(currentNode、currentCar、currentCustomer);
openUpdate(当前节点,临时);
}
}
}
返回当前节点;
}
现在,对于childrensearchnode,我想删除它所服务的客户。但这应该只发生在搜索节点内部

这就是SearchNode类中发生的情况:

public class SearchNode implements Comparable<SearchNode> {

List<Car> allCars;
List<Customer> allCustomers;
SearchNode parent;

public SearchNode(SearchNode parent, Car currentCar, Customer currentCustomer) {
    // inheriting values from parent search node
    this.allCars = parent.allCars; 
    this.allCustomers = parent.allCustomers;
    this.parent = parent;

    // now updating this node's values
    this.allCustomers.remove(currentCustomer);
}
public类SearchNode实现可比较的{
列出所有汽车;
列出所有客户;
搜索节点父节点;
公共SearchNode(SearchNode父节点、Car currentCar、Customer currentCustomer){
//从父搜索节点继承值
this.allCars=parent.allCars;
this.allCustomers=parent.allCustomers;
this.parent=parent;
//现在正在更新此节点的值
此.allCustomers.remove(currentCustomer);
}
我检查了一些打印件,在
的第二次迭代中(itrCar.hasNext())
,父级的
allCustomer
列表缺少
currentCustomer


编辑:我更想问:有人能告诉我为什么更改父节点的值吗?这可能是因为我还不了解整个java实际上是通过引用传递的。

您应该创建一份
列表的副本,您想从中本地删除客户:

public SearchNode(SearchNode parent, Car currentCar, Customer currentCustomer) {
    // inheriting values from parent search node
    this.allCars = parent.allCars; // consider making a copy here too
                                   // if required
    this.allCustomers = new ArrayList<>(parent.allCustomers); // make a 
                                                              // copy
    this.parent = parent;

    // now updating this node's values
    this.allCustomers.remove(currentCustomer); // now you can safely 
                                               // remove currentCustomer
                                               // without affecting 
                                               // parent.allCustomers
}
public SearchNode(SearchNode父节点、Car currentCar、Customer currentCustomer){
//从父搜索节点继承值
这也算是父母。
//如有需要
this.allCustomers=newarraylist(parent.allCustomers);//创建一个
//抄袭
this.parent=parent;
//现在正在更新此节点的值
this.allCustomers.remove(currentCustomer);//现在您可以安全地
//删除当前客户
//不影响
//家长。所有客户
}

所有包含对象(如列表)的变量本质上都是指针(挑剔者可能不同意确切的术语,但我相信这已经足够接近了)。所以当你说

this.allCustomers = parent.allCustomers
this.allCustomers和parent.allCustomers现在指向同一个列表对象。然后

this.allCustomers.remove(currentCustomer)
正在该列表上运行.remove(),该列表是父级的allCustomers…当前正在迭代。由于该列表已被修改,因此迭代失败


为了澄清对该问题的评论,“Java是100%按值传递的。对对象的引用是按值传递的。”这意味着您无法从C语言[1]实现函数“swap”,因为该函数获取副本(值)一个函数可以修改给定指针/引用的对象的属性,并使这些修改对传入对象的调用方可见,因为它们引用相同的对象。基元类型(int、boolean等)按值传递,但它们是不可变的(您可以说x=3,然后x=5,但没有3.changeValueTo(5)),因此差异在很大程度上可以忽略

···


[1] :这就是禁止使用不安全的类,该类可以直接访问内存。不要使用它,因为它会严重破坏东西。聪明的工程师可以永远使用它(例如,Java内部有时使用它),无论如何都不需要我的建议。

“有人能告诉我如何更改父节点的值吗?”
this.allCustomers.remove(currentCustomer);
,因为
this.allCustomers=parent.allCustomers
。Java是100%按值传递的。对对象的引用是按值传递的。@AndyTurner是的,但我认为这是(在前面)将仅更改节点内的值。而不是仅为创建新对象实例而传递的父节点的值…?此时,我是否可以询问将ArrayList初始化为
new ArrayList(parent.allCustomers);
与您的建议之间的区别?