【问题标题】:Java: set-size List issue UnsupportedOperationException thrownJava:设置大小列表问题抛出 UnsupportedOperationException
【发布时间】:2011-02-14 07:39:00
【问题描述】:

我在更改具有 Java 中设置大小的列表时遇到问题。

我知道我无法在此列表中添加或删除,但为什么我不能使用 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). 

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

编辑: 我正在使用链接列表

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

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)

【问题讨论】:

  • java.util.List 是一个接口。您使用的是哪种实现方式?
  • 听起来你在使用Collections.unmodifiableList,它是不可修改的,不仅在大小上而且在内容上。
  • 根据 Sun 的说法,LinkedList 应该支持该操作。
  • 其实有办法查出它是什么类型的List吗?因为我最初将它设置为 LinkedList 但后来我将其设置为另一个列表(我不确定的类型)
  • @tuckster:我认为您可以通过发布异常的堆栈跟踪来回答所有问题(好吧,不是全部)。要找出列表的类型System.out.println(yourList); 应该会给你信息。

标签: java list


【解决方案1】:

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

您使用的实际列表类型是什么?数组列表?链表?自定义类型?

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

【讨论】:

  • 不应该是评论而不是回答?
【解决方案2】:

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

如果它是 List 的某个第 3 部分库实现,则该实现可能根本不支持该操作(因此出现异常)。

【讨论】:

    【解决方案3】:

    你可以从你的stacktrace中看到,使用的Listpolyglot.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 的此实现不允许更改(如果构造为不可变)。

    【讨论】:

    • 我的问题已通过创建一个新的 TypedList 并将旧列表中的所有元素以及我想要添加或更改的新元素插入到新列表中来解决。
    【解决方案4】:

    这里有一些修复建议

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

    例如

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-02-26
      • 2022-01-22
      • 2014-01-30
      • 1970-01-01
      • 1970-01-01
      • 2018-10-20
      • 2014-09-06
      • 1970-01-01
      相关资源
      最近更新 更多