我正在审查AP计算机科学A考试,我写的代码与答案略有不同。你认为你可以检查每个输出是否相同?
目标:从CookieOrder ArrayList订单中删除特定类型的Cookie订单,并返回已删除的框数。 请假设所有方法都按照建议工作。
答案:
public int removeVariety(String cookieVar) { int boxesRemoved = 0; for (int i = orders.size() - 1; i >= 0; i--) { if (cookieVar.equals(orders.get(i).getVariety())) boxesRemoved += orders.remove(i).getNumBoxes(); }
返回框已删除; }
我放的是什么:
public int removeVariety(String cookieVar) { String cookieType = cookieVar; int totalRemoved = 0; for(CookieOrder boxes : this.order) { String type = boxes.getVariety(); int totalBoxesCookieOrder = boxes.getNumBoxes(); if(type.equals(cookieType)) { totalRemoved += totalBoxesCookieOrder; this.order.remove(boxes); } } return totalRemoved; }
这还能用吗?或者,如果你想给我评分,这里是scoring rubric(问题1,B部分)。我很感激帮助;测试是明天,我非常紧张。
答案 0 :(得分:3)
这还能用吗?
您的代码将失败并显示ConcurrentModificationException
,因为您在迭代时正在修改集合。
模型答案通过使用索引而不是Iterator
...并从尾部到列表的头部来避免这种情况。
避免CME问题的另一种方法是使用显式迭代器,并使用Iterator.remove()
方法进行删除。 (这适用于ArrayList
或LinkedList
,但某些更具异国情调的列表类型可能会因某种原因返回不支持Iterator
的{{1}}。)
答案 1 :(得分:2)
正如其他人所提到的,这会抛出一个ConcurrentModificationException
因为你在迭代它时从列表中删除了一个项目。
安全的方法是使用迭代器。 Iterator
是一个内置类,所有集合(包括ArrayList
)都必须提供。迭代器为您提供了一种迭代列表的方法(很像您使用的for
- 循环),但也允许您从集合中安全地删除元素。
首先从ArrayList
的{{1}}方法获取迭代器。与iterator
一样,ArrayList
泛型 - 也就是说,它是Iterator
,而不仅仅是Iterator<CookieOrder>
。
Iterator
Iterator<CookieOrder> iterator = order.iterator();
类有两个关键方法:Iterator
和hasNext
。您想检查每个项目,直到没有项目为止。每当你调用next
时,都会将迭代器推进一个。你的代码看起来像这样:
next
特别针对您的问题:
// Make sure there are still items in the array.
while (iterator.hasNext()) {
// Get the item.
CookieOrder o = iterator.next();
// do something with o
}
对于得分规则(B部分):
Iterator<CookieOrder> iterator = order.iterator();
while (iterator.hasNext()) {
// Get the boxes cookie order.
CookieOrder boxes = iterator.next();
// Perform the same check as before.
String type = boxes.getVariety();
int totalBoxesCookieOrder = boxes.getNumBoxes();
if(type.equals(cookieType))
{
totalRemoved += totalBoxesCookieOrder;
// Here's where we want to remove it.
//
// Instead of calling order.remove, we can use the
// "remove" method of the iterator. This is safe.
iterator.remove();
}
}
的元素(虽然隐含地,使用this.orders
)boxes
(cookieVar
)与cookieType
的结果进行比较getVariety()
totalRemoved
getNumBoxes
的总数(尽管他们可能会选择不为+=
提供这一点,但根据我的经验,他们只会对错误进行一次处罚)< / LI>
此部分的总分: 4/6 。
请记住,该分数仅适用于该部分;推断,你的问题得分可能是6/9,已经高于平均得分(5.46)。还要记住,这些不是线性分级的;即50%的问题是正确的。
祝你的考试好运!
答案 2 :(得分:1)
此外,当您删除时 - 不应该在该迭代上推进循环索引。如果您的要求是删除多个匹配项,则需要处理。
两种形式的循环都会遇到问题;第三种形式没有。
for(a : b)
将遭受ConcurrentModificationException,并且循环索引将无法正确推进; for (int i = 0; i < size; i++)
或(反方向)i--
不会遭遇异常,但删除项目时元素会移动;除非您补偿,否则i++
会错误地推进循环索引; Iterator<CookieOrder>
有一个remove()
方法,它可以正确地补偿循环索引。不会遭受ConcurrentModificationException。示例:
Iterator<CookieOrder> it = orders.iterator();
while (it.hasNext()) {
CookieOrder cand = it.next(); // 'candidate' for consideration/ removal
if (cand.getVariety. equals( type)) {
// Remove; iterator.remove() handles the loop index correctly.
boxesRemoved += cand.getNumBoxes();
it.remove();
}
}