从Collection<? extends MyObject>中删除项目 UnsupportedOperationException。

3

我有一个关于函数的问题。 这段代码对我来说运行得相当好,它会在布尔属性为真时删除一个项:

private void doRemoveAusgefallenePlaene(Collection<CarPlan> pAllCarPlan) {
for (Iterator<CarPlan> lCarPlanIterator = pAllCarPlan.iterator(); lCarPlanIterator.hasNext();) {
  CarPlan lCarPlan = lCarPlanIterator.next();
  if (!lCarPlan.isAusfall()) {
    lCarPlanIterator.remove();
  }
}
}

我希望能够对实现接口PlanCarPlanShipPlan对象使用该函数。请注意,不要删除或更改HTML标签。
private void doRemoveAusgefallenePlaene(Collection<? extends Plan> pAllPlan) {
  for (Iterator<? extends Plan> lIterator = pAllPlan.iterator(); lPlanIterator.hasNext();) {
    Plan lPlan = lPlanIterator.next();
    if (!lPlan.isAusfall()) {
      lPlanIterator.remove();
    }
  }
}

现在我可以使用类型为CarPlanShipPlanCollections调用该函数。
doRemoveAusgefallenePlaene(pAllCarPlan);
doRemoveAusgefallenePlaene(pAllShipPlan);

代码能够顺利编译。不幸的是,在执行时,UnsopportedOperationException在该行抛出。

lPlanIterator.remove();

我觉得我在声明Collection<? extends Plan>时理解错了一些东西。有人知道问题是什么吗?
-- 更新 -- 对于那些对一种可能的解决方案感兴趣的人:
final List<CarPlan> lAllCarPlan = new ArrayList<CarPlan>(pAllCarPlan);
doRemoveAusgefallenePlaene(lAllCarPlan);

ShipPlanCarPlan组合使用效果很好。

你尝试过使用 Collection<Plan> 吗? - Evan Knowles
是的,但是我就不能传递类型为ShipPlan或CarPlan的集合。我所描述的函数是业务案例doSomethingWithShip和doSomethingWithCar的一部分。我没有接口变量,也不允许进行类型转换。 - s_bei
2个回答

6
你可能正在迭代一个不可修改的集合,因此其迭代器不支持删除操作。
不可修改的集合示例包括由 Collections.unmodifiableXX() 生成的集合。由 Arrays.asList() 返回的列表并非完全不可修改(您可以在特定索引处设置元素),但由于直接由传入的数组支持,因此不支持添加或删除操作。
remove() 的 Javadoc 可以看到:

如果此迭代器不支持删除操作,则引发: UnsupportedOperationException

您需要查看您正在传入的内容,并确保集合的结构实际上可以被修改。 您还没有向我们展示该代码。

那么将集合转换为列表就可以解决问题了吗? - s_bei
1
@StefanBe:这取决于列表。主要的ArrayListLinkedList是结构可修改的,因此它们的迭代器支持删除。正如我所说,由Arrays.asList()创建的列表不支持它。 - Mark Peters

2

以下是来自@dmeister的另一个回答:为什么Java集合中的删除方法不是通用的?

Josh Bloch和Bill Pugh在“Java Puzzlers IV:幽灵引用威胁,克隆攻击和变形的复仇”(Google TechTalk)中提到了这个问题。

Josh Bloch说(6:41),他们试图将Map的get方法、remove方法和一些其他方法变成通用的,但“它根本行不通”。如果你只允许将集合的通用类型作为参数类型,那么有太多合理的程序无法变成通用的。他给出的例子是数字列表和长整型列表的交集。


我不确定这与问题的相关性。 Stefan 没有尝试使用集合的 remove 方法。 - Mark Peters

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接