【问题标题】:List object reference changed during Java loop列表对象引用在 Java 循环期间更改
【发布时间】:2015-04-26 16:29:38
【问题描述】:

我找不到任何关于此的主题。我想知道在像下面这样的循环期间更改列表类的引用是否安全:

Tree minimalTree = someTree;
for (Tree st : minimalTree.getSubtrees()) {
  if (condition)
    minimalTree = st;
}

迭代器是否被重置并重新启动以获取新引用?

编辑:我忘了说:这段代码适用于我想缩小树中元素搜索范围的情况,比如包含某些元素的较小树。在这种情况下,继续只寻找“min​​imalTree”的内部结构而不是整个“someTree”结构会更快。

【问题讨论】:

  • 测试时会发生什么?
  • 您可能应该为此使用递归调用。
  • 到目前为止它似乎工作正常,但我不确定它是否适用于大规模处理。但也许@biziclop 是对的,应该避免这种编码......
  • 问题已经得到解答,关于替代实现的建议可能不会算作“答案”,因此只需评论:与此处给出的建议相反:您应该 使用递归调用来解决这个问题 - 至少要考虑到即使对于中等大小的树,您也可能很容易遇到 StackOverflowError

标签: java loops iterator


【解决方案1】:

不,迭代不会被重置。根据JLS

增强的 for 语句等价于基本的 for 语句 形式:

for (I #i = Expression.iterator(); #i.hasNext(); ) {
     {VariableModifier} TargetType Identifier = (TargetType) #i.next();
     Statement
}

该定义清楚地表明,迭代器仅在循环的第一次迭代之前初始化一次。

使用增强的 for 语句遍历数组时的行为在这方面是相似的。

但我个人认为这是不好的做法,因为它使代码难以理解。

【讨论】:

    【解决方案2】:

    其实有两个问题:

    我想知道在如下循环中更改列表类的引用是否安全:

    是的,它是安全的。为了安全起见,我的意思是:更改引用不会干扰已经运行的循环。

    迭代器是否被重置并重新启动以获取新引用?

    不,迭代器永远不会重置。这与安全正好相反。

    在我看来,在循环中更改迭代器或集合变量不是一个好习惯。它使代码更难理解,并且当你这样做时结果可能不是你所期望的(就像在你的情况下,我理解你期望循环重新开始重新评估集合)。

    在您的情况下,封装在一个方法中并在子树上递归调用它:

    Tree findMinimalTree(Tree tree) {
       for (Tree st : tree.getSubtrees()) {
         if (condition)
           return findMinimalTree(st);
       }
       return tree;
    }
    

    【讨论】:

    • 我不同意。阅读biziclop的答案。用我的话来说,minimalTree.getSubtrees()[.iterator()] 在进入循环时只被评估一次。之后,您可以让 minimumTree 引用指向您想要的任何内容。请记住,分配 minimumTree = st 不会更改先前由 minimumTree 引用的对象(C++ 会在这里做的事情)。它只是更改了引用的最小树,即。 e.对象 minimumTree 指向。
    • 是的,我理解你的观点。在我看来,问题在于 (i) 乍一看,它似乎像 c++ 对应物一样工作,并且 (ii) 当您调试时,您再也看不到您正在迭代的集合。
    • “它似乎工作”不是恰当的表达方式,我会努力改进它。有什么建议吗?
    • 我越想你的答案,我就会有新的方法来解释它。你想说什么吗?比如:“赋值“minimalTree = st;”是合法的;但迭代器仍然迭代原始集合;这似乎不是你所期望的。 ?
    • 我又改了,请查看。如果你想帮忙,我可以把它转成维基。
    猜你喜欢
    • 2021-05-14
    • 2014-08-17
    • 1970-01-01
    • 2022-09-27
    • 2019-06-24
    • 2015-06-27
    • 2021-12-23
    • 1970-01-01
    • 2021-11-13
    相关资源
    最近更新 更多