Java:set-size List问题抛出UnsupportedOperationException

时间:2010-04-30 16:21:46

标签: java list

我在更改Java中具有set-size的List时遇到问题。

我知道我无法在此列表中添加或删除,但为什么我不能使用set? 当我使用set时,抛出UnsupportedOperationException以及当我使用add和remove时,它是预期的。

public Object set(int index,
                  Object element)

    Replaces the element at the specified position in this list with the specified element (optional operation). 

我理解它的一个可选操作,只是想用另一个元素替换列表中的那个元素。 有什么方法可以做到这一点吗?

编辑: 我正在使用LinkedList

这是我的问题的堆栈跟踪。

java.lang.UnsupportedOperationException: Add to an immutable TypedListIterator
    at polyglot.util.TypedList.tryIns(TypedList.java:195)
    at polyglot.util.TypedList.set(TypedList.java:148)
    at itype.visit.ItypeChecker.enter(ItypeChecker.java:114)
    at polyglot.visit.NodeVisitor.visitEdgeNoOverride(NodeVisitor.java:245)
    at polyglot.visit.NodeVisitor.visitEdge(NodeVisitor.java:217)
    at polyglot.ast.Node_c.visitChild(Node_c.java:173)
    at polyglot.ast.Node_c.visitList(Node_c.java:233)
    at polyglot.ast.ClassBody_c.visitChildren(ClassBody_c.java:63)
    at polyglot.visit.NodeVisitor.visitEdgeNoOverride(NodeVisitor.java:251)
    at polyglot.visit.NodeVisitor.visitEdge(NodeVisitor.java:217)
    at polyglot.ast.Node_c.visitChild(Node_c.java:173)
    at polyglot.ast.ClassDecl_c.visitChildren(ClassDecl_c.java:159)
    at polyglot.visit.NodeVisitor.visitEdgeNoOverride(NodeVisitor.java:251)
    at polyglot.visit.NodeVisitor.visitEdge(NodeVisitor.java:217)
    at polyglot.ast.Node_c.visitChild(Node_c.java:173)
    at polyglot.ast.Node_c.visitList(Node_c.java:233)
    at polyglot.ast.SourceFile_c.visitChildren(SourceFile_c.java:121)
    at polyglot.visit.NodeVisitor.visitEdgeNoOverride(NodeVisitor.java:251)
    at polyglot.visit.NodeVisitor.visitEdge(NodeVisitor.java:217)
    at polyglot.ast.Node_c.visit(Node_c.java:177)
    at polyglot.frontend.VisitorPass.run(VisitorPass.java:56)
    at polyglot.frontend.Scheduler.runPass(Scheduler.java:596)
    at polyglot.frontend.Scheduler.runGoal(Scheduler.java:499)
    at polyglot.frontend.Scheduler.attemptGoal(Scheduler.java:440)
    at polyglot.frontend.Scheduler.attemptGoal(Scheduler.java:412)
    at polyglot.frontend.Scheduler.attemptGoal(Scheduler.java:412)
    at polyglot.frontend.Scheduler.attemptGoal(Scheduler.java:412)
    at polyglot.frontend.Scheduler.attemptGoal(Scheduler.java:364)
    at polyglot.frontend.Scheduler.runToCompletion(Scheduler.java:297)
    at polyglot.frontend.Compiler.compile(Compiler.java:171)
    at polyglot.frontend.Compiler.compileFiles(Compiler.java:138)
    at polyglot.main.Main.start(Main.java:119)
    at polyglot.main.Main.start(Main.java:82)
    at polyglot.pth.SourceFileTest.invokePolyglot(SourceFileTest.java:162)
    at polyglot.pth.SourceFileTest.runTest(SourceFileTest.java:60)
    at polyglot.pth.AbstractTest.run(AbstractTest.java:32)
    at polyglot.pth.TestSuite.runTest(TestSuite.java:64)
    at polyglot.pth.ScriptTestSuite.runTest(ScriptTestSuite.java:55)
    at polyglot.pth.AbstractTest.run(AbstractTest.java:32)
    at polyglot.pth.Main.start(Main.java:41)
    at polyglot.pth.Main.main(Main.java:11)

4 个答案:

答案 0 :(得分:3)

您可以在堆栈跟踪中看到它,List使用的是polyglot.util.TypedList,可以构造为不可变的。

set调用tryIns,检查列表是否不可变(see source):

private  final void tryIns(Collection coll) {
  if (immutable)
    throw new UnsupportedOperationException JavaDoc(
                    "Add to an immutable TypedListIterator");

正如您已经发现的那样setoptional operation,并且此List的此实现不允许更改(如果构造为immutable)。

答案 1 :(得分:0)

列表是一个界面。它(像Collection)定义了可选操作。 可选操作是接口的一部分(为了保持一致性),但不能保证子类型实际上支持它们(它违反了行为子类型)。换句话说,并非列表的所有实际实现都必须支持这些操作,它们只需要记录它们是否存在。

您使用的是哪种实际列表类型?数组列表? LinkedList的?自定义类型?

据我所知,ArrayList DOES支持set操作。 我不确定LinkedList 如果您有自定义实现,除非您覆盖该方法,否则它可能不支持它。

答案 2 :(得分:0)

List不是一个类,它只是一个接口。您是否正在实施自己的List?或者使用预定义的?

如果它是List的第三部分库实现,那么该实现可能根本不支持该操作(因此例外)。

答案 3 :(得分:0)

以下是一些修复建议

  1. 如果您的代码创建了原始列表,则更改构造函数调用以使其可变。
  2. 否则,如果ITypeChecker.enter()中的代码允许您替换列表引用,则可以创建可变列表并使用它,
  3. e.g。

    List immutable = ....; // your immutable list
    List mutable = new LinkedList(immutable);
    // pass `mutable` to the rest of your code so the new list is used