【问题标题】:Java ternary operator and setting loop index valuesJava 三元运算符和设置循环索引值
【发布时间】:2011-05-23 16:08:57
【问题描述】:

我有一个循环通过 ArrayList 的 for 循环。

如果在for循环中满足条件:

  • 我从ArrayList 中删除了当前元素
  • 减小ArrayList局部变量的大小
  • 像这样减少 for 循环的索引,检查以确保它们永远不会低于零。

我们刚刚删除了ArrayList的最后一个元素的情况:

i = (i > 0) ? i-- : i;

我的问题是,当 i > 0 时,上述内容不会将 i 减 1。我无数次使用三元运算符,但从未见过这种行为。我已经测试过 i 确实 > 0 并且 i-- 部分正在被调用。它根本不会减少 i 的值。删除 0 值检查并简单地运行 i--; 确实会按预期减少 i。

EDIT2:好的,有人编辑了我的最后一次编辑,我提到在这种情况下我特别不使用 ListIterator,因为循环本身的性能敏感性质,在 Android 代码的关键部分。

【问题讨论】:

    标签: java ternary-operator


    【解决方案1】:

    i--递减i,但返回原始值。

    i = i-- 将递减i,然后将其赋值为原始值。

    你应该使用i - 1

    【讨论】:

      【解决方案2】:

      最小的修复:

      你可能会追求这样的东西:

      for (int i = 0; i < l.size(); i++) {         <--------------------------------.
          if (cond) {                                                               |
              l.remove(i);                                                          |
              i--;              // even if i == -1, it will be set back to 0 here --'
          }
      }
      

      改为向后迭代:

      另一种常见的解决方案是向后迭代,如下所示:

      for (int i = l.size() - 1; i >= 0; i--) {
          if (cond) {
              l.remove(i);
          }
      }
      

      使用ListIterator(除非对性能至关重要):

      但是,您可以通过ListIterator 获得甚至更好

      Iterator<String> iter = l.iterator();
      while (iter.hasNext()) {
          if (shouldRemove(iter.next())
              iter.remove();
      }
      

      【讨论】:

        【解决方案3】:

        你试过了吗?:

        i = (i > 0) ? --i : i;
        

        通过预减量,您应该可以解决所有问题。

        【讨论】:

        • 在这里使用递减运算符和i = ... 是多余的(并且会产生误导)。
        【解决方案4】:

        分配诸如i = i--(发生在i &gt; 0)之类的任务根本没有意义:您到底期待什么?请改用以下内容:

        i = (i > 0) ? i - 1 : i;
        

        或者,甚至更好:

        if (i > 0)
            i--;
        

        【讨论】:

          【解决方案5】:

          做正确的事:使用迭代器循环遍历您的数组列表并在迭代时安全地删除项目。

          【讨论】:

            【解决方案6】:

            您所描述的算法对于您正在尝试做的事情来说是一个糟糕的策略:从 ArrayList 中删除一个元素是一个 O(n) 操作,因此将其应用于整个 ArrayList 通常是 O(n^2)案例。

            更好的策略:

            • 新建一个空的ArrayList
            • 在原始 ArrayList 中循环一次,并仅将要保留的元素添加到新的 ArrayList 中

            这是 O(n),实际上是更简单的代码(您不必担心摆弄循环边界等)

            【讨论】:

            • +1 这并不能回答我遇到的具体三元问题(我已将该答案授予其他人),但就我删除某些项目的更大目标而言确实更有意义在 O(n) 中,因为我没有考虑到 ArrayList.remove() 也是 O(n)。谢谢!
            【解决方案7】:

            考虑不要使用带 noop 的三元运算符。

            如果 (i > 0) { - 一世 }

            准确描述您想要的功能(基于您的示例)。

            【讨论】:

              【解决方案8】:

              正如其他人所说,i-- 递减 i 并返回原始值,这意味着您的代码将执行递减,但随后立即将其设置回原始值。

              您可以将其切换为--i,在这种情况下将返回递减的值,但无论哪种方式,您都在使用--进行不必要的工作,因为它必须设置i,返回新值,然后再次将i 设置为新值。

              你最好只做i-1,它不会设置i的值两次:

              i = (i > 0) ? i-1 : i;
              

              话虽如此,由于三元的 false 选项没有任何作用,您可能最好直接使用 if()

              if(i > 0) { i--; }
              

              它更易于阅读,无论-- 走哪条路都没有关系,并且无论结果如何,都不会进行任何不必要的处理。

              【讨论】:

                猜你喜欢
                • 2012-12-26
                • 2022-01-04
                • 1970-01-01
                • 2013-06-28
                • 1970-01-01
                • 1970-01-01
                • 2017-05-21
                • 2014-02-08
                相关资源
                最近更新 更多