【问题标题】:Infinite loop using an iterator使用迭代器的无限循环
【发布时间】:2018-04-12 08:51:55
【问题描述】:

我是迭代器的新手,不确定自己做错了什么。在我的项目中,车站有有乘客的汽车,汽车也可以有乘客。我的目标是检查汽车是否已到达其目标车站,如果没有,则将其从当前车站移除并将其添加到下一个车站,从而将其移动到下一个车站。

        Iterator<Station> stations = allStations.iterator();
        while(stations.hasNext())
        {
            Station currentStation = (Station)stations.next();
            ArrayList<Car> currentStationCars = currentStation.getCarList();
            Iterator cars = currentStationCars.iterator();
            Car currentCar = (Car)cars.next();
            while(cars.hasNext())
            {

最初,我在这里声明了 currentCar,但这导致了 NoSuchElement 异常——我猜是因为我在每次迭代时都不断向前移动光标。不确定,我一个小时前才知道这个。现在,这段代码导致了一个无限循环。

                //original position of currentCar declaration
                int stepper = 0;
                if(currentCar.getCurrentLocation() < currentCar.getDestination())
                {
                    stepper = 1;
                }
                else if(currentCar.getCurrentLocation() > currentCar.getDestination())
                {
                    stepper = -1;
                }
                while(stepper != 0)
                {
                    currentCar.setCurrentLocation(currentCar.getCurrentLocation() + stepper);
                    currentStation.removeCar(currentCar);
                    if(currentCar.getCurrentLocation() < currentCar.getDestination())
                    {
                        stepper = 1;
                    }
                    else if(currentCar.getCurrentLocation() > currentCar.getDestination())
                    {
                        stepper = -1;                       
                    }
                    else { 
                        stepper = 0; 
                    }
            }
        }

【问题讨论】:

  • 你永远不会在 while 循环中调用 currentCar.next()stations.next()
  • 使用调试器找出发生了什么

标签: java iterator infinite-loop nosuchelementexception


【解决方案1】:

您只在循环之前推进迭代器一次。这意味着如果列表为空(因为在检查 cars.hasNext() 之前调用了 cars.next()),您将收到异常,如果它至少有一个元素,则会出现无限循环,因为您不会前进到下一个Car 在循环内。

你应该只在循环内推进迭代器:

while (cars.hasNext())
{
    Car currentCar = (Car)cars.next();
    ....
}

请注意,如果您使用泛型类型,则可以避免强制转换:

Iterator<Car> cars = currentStationCars.iterator();
...
while(cars.hasNext())
{
    Car currentCar = cars.next();
    ....
}

【讨论】:

  • 感谢您的回答。这就说得通了;但是,将该行移回原来的位置会导致并发修改异常。知道为什么吗?
  • @Mauve 如果currentStation.removeCar(currentCar); 将汽车从currentStation.getCarList() 返回的列表中删除,这就是异常的原因。将其替换为cars.remove()。这是在迭代列表时从列表中删除元素的安全方法。
猜你喜欢
  • 1970-01-01
  • 2017-05-02
  • 2014-10-31
  • 2015-03-02
  • 1970-01-01
  • 2023-03-20
  • 1970-01-01
  • 2017-09-08
  • 1970-01-01
相关资源
最近更新 更多