IndexOutOfBoundsException:我在 while 循环中看不到
IndexOutOfBoundsException: I don't see in my while loop
我一直卡在这个我无法理解的 IndexOutOfBoundsException
上,我不明白为什么它指向我的 while
循环。关于做什么的任何建议?顺便说一句,该方法是一个循环调度模拟器,它似乎可以与我的一个测试文件完美配合,但不能与另一个测试文件配合使用。
public void roundRobin2(ArrayList<Jobs> c, int startSize)
{
//int n = 0;
double counter = 0;
double compTime = 0;
while(!c.isEmpty())
{
int i = 0;
System.out.println(c);
for(i = 0; i < c.size(); i++)
{
if((c.get(i).jobTime) >= 2)
{
c.get(i).jobTime -= 2;
counter += 2;
if((c.get(i).jobTime) == 0)
{
compTime += counter;
}
}
else
{
(c.get(i).jobTime) -= 1;
counter += 1;
if((c.get(i).jobTime) == 0)
{
compTime += counter;
}
}
//System.out.print("-" + c.get(i).jobName + "-" + counter);
//n++;
//if(n%10 == 0)
//{
//System.out.println("\n");
//}
}
for(i = 0; i < c.size(); i++)
{
while(!c.isEmpty() && (c.get(i).jobTime) == 0)
{
c.remove(i);
}
}
}
System.out.println("\n\nAverage completion times: "+ compTime + "/" + startSize +" = " + ((compTime)/startSize));
}
异常堆栈跟踪:
Exception in thread "main" java.lang.IndexOutOfBoundsException: Index: 7, Size: 7
at java.util.ArrayList.rangeCheck(Unknown Source)
at java.util.ArrayList.get(Unknown Source)
at cs431.edu.cpp.Main.roundRobin2(Main.java:143)
您正在删除正在迭代的 collection 中的项目,这非常糟糕,您永远不应该这样做。您可以使用具有 remove
方法的 Iterator
来执行此操作(但这很少有效),或者制作 collection 的临时副本。顺便说一句 round-robin 可以更容易地实施。
这个方案使用了一个LinkedList
,因为在头部移除和在尾部插入都是O(1)
,这样既高效又安全。我还压缩了你的一些逻辑作为奖励:
public void roundRobin2(List<Jobs> jobs, int startSize) {
double counter = 0;
double compTime = 0;
Deque<Jobs> uncompletedJobs = new LinkedList<>(jobs);
while (!uncompletedJobs.isEmpty()) {
Job job = uncompletedJobs.pop();
int taskTime = job.jobTime >= 2 ? 2 : 1;
job.jobTime -= taskTime;
counter += taskTime;
if (job.jobTime == 0) {
compTime += counter;
} else {
uncompletedJobs.addLast(job);
}
}
jobs.clear();
System.out.println("\n\nAverage completion times: "+ compTime + "/" + startSize +" = " + ((compTime)/startSize));
}
您的代码:
while(!c.isEmpty() && (c.get(i).jobTime) == 0)
{
c.remove(i);
}
如果 i
正在删除最后一个元素,但不会导致列表变空, 将失败。改用这个:
while (i < c.size() && c.get(i).jobTime == 0)
{
c.remove(i);
}
更新
您的代码将通过使用 for (obj : list)
循环进行大量清理,您应该使用 Iterator
删除元素。这是清理后的代码:
public static void roundRobin2(ArrayList<Jobs> c, int startSize)
{
double counter = 0;
double compTime = 0;
while (! c.isEmpty())
{
System.out.println(c);
for (Jobs jobs : c)
{
if (jobs.jobTime >= 2)
{
jobs.jobTime -= 2;
counter += 2;
}
else
{
jobs.jobTime -= 1;
counter += 1;
}
if (jobs.jobTime == 0)
{
compTime += counter;
}
}
for (Iterator<Jobs> jobsIter = c.iterator(); jobsIter.hasNext(); )
{
Jobs jobs = jobsIter.next();
if (jobs.jobTime == 0)
{
jobsIter.remove();
}
}
}
System.out.println("\n\nAverage completion times: " + compTime + "/" + startSize + " = " + (compTime / startSize));
}
我一直卡在这个我无法理解的 IndexOutOfBoundsException
上,我不明白为什么它指向我的 while
循环。关于做什么的任何建议?顺便说一句,该方法是一个循环调度模拟器,它似乎可以与我的一个测试文件完美配合,但不能与另一个测试文件配合使用。
public void roundRobin2(ArrayList<Jobs> c, int startSize)
{
//int n = 0;
double counter = 0;
double compTime = 0;
while(!c.isEmpty())
{
int i = 0;
System.out.println(c);
for(i = 0; i < c.size(); i++)
{
if((c.get(i).jobTime) >= 2)
{
c.get(i).jobTime -= 2;
counter += 2;
if((c.get(i).jobTime) == 0)
{
compTime += counter;
}
}
else
{
(c.get(i).jobTime) -= 1;
counter += 1;
if((c.get(i).jobTime) == 0)
{
compTime += counter;
}
}
//System.out.print("-" + c.get(i).jobName + "-" + counter);
//n++;
//if(n%10 == 0)
//{
//System.out.println("\n");
//}
}
for(i = 0; i < c.size(); i++)
{
while(!c.isEmpty() && (c.get(i).jobTime) == 0)
{
c.remove(i);
}
}
}
System.out.println("\n\nAverage completion times: "+ compTime + "/" + startSize +" = " + ((compTime)/startSize));
}
异常堆栈跟踪:
Exception in thread "main" java.lang.IndexOutOfBoundsException: Index: 7, Size: 7
at java.util.ArrayList.rangeCheck(Unknown Source)
at java.util.ArrayList.get(Unknown Source)
at cs431.edu.cpp.Main.roundRobin2(Main.java:143)
您正在删除正在迭代的 collection 中的项目,这非常糟糕,您永远不应该这样做。您可以使用具有 remove
方法的 Iterator
来执行此操作(但这很少有效),或者制作 collection 的临时副本。顺便说一句 round-robin 可以更容易地实施。
这个方案使用了一个LinkedList
,因为在头部移除和在尾部插入都是O(1)
,这样既高效又安全。我还压缩了你的一些逻辑作为奖励:
public void roundRobin2(List<Jobs> jobs, int startSize) {
double counter = 0;
double compTime = 0;
Deque<Jobs> uncompletedJobs = new LinkedList<>(jobs);
while (!uncompletedJobs.isEmpty()) {
Job job = uncompletedJobs.pop();
int taskTime = job.jobTime >= 2 ? 2 : 1;
job.jobTime -= taskTime;
counter += taskTime;
if (job.jobTime == 0) {
compTime += counter;
} else {
uncompletedJobs.addLast(job);
}
}
jobs.clear();
System.out.println("\n\nAverage completion times: "+ compTime + "/" + startSize +" = " + ((compTime)/startSize));
}
您的代码:
while(!c.isEmpty() && (c.get(i).jobTime) == 0)
{
c.remove(i);
}
如果 i
正在删除最后一个元素,但不会导致列表变空,将失败。改用这个:
while (i < c.size() && c.get(i).jobTime == 0)
{
c.remove(i);
}
更新
您的代码将通过使用 for (obj : list)
循环进行大量清理,您应该使用 Iterator
删除元素。这是清理后的代码:
public static void roundRobin2(ArrayList<Jobs> c, int startSize)
{
double counter = 0;
double compTime = 0;
while (! c.isEmpty())
{
System.out.println(c);
for (Jobs jobs : c)
{
if (jobs.jobTime >= 2)
{
jobs.jobTime -= 2;
counter += 2;
}
else
{
jobs.jobTime -= 1;
counter += 1;
}
if (jobs.jobTime == 0)
{
compTime += counter;
}
}
for (Iterator<Jobs> jobsIter = c.iterator(); jobsIter.hasNext(); )
{
Jobs jobs = jobsIter.next();
if (jobs.jobTime == 0)
{
jobsIter.remove();
}
}
}
System.out.println("\n\nAverage completion times: " + compTime + "/" + startSize + " = " + (compTime / startSize));
}