【问题标题】:while-else-loopwhile-else-循环
【发布时间】:2012-06-03 04:44:21
【问题描述】:

当然,这在 java 中是不可能的(迄今为止),但理想情况下,我希望实现它,因为它是许多迭代的核心。例如,当它创建ArrayList 时,它被调用的第一次多次被调用了 650,000 多次。 不幸的是,我的实际代码在else 循环内没有set;因此它将通过addset 命令并浪费时间。

之后我将它放在另一个循环中,它只执行集合,因为数据已经创建,并且在许多其他循环中是多重嵌套的,所以这是一个漫长的过程。

ArrayList<Integer>  dataColLinker = new java.util.ArrayList<Integer>();
...
...
public void setLinkerAt( int value, int rowIndex) {
    ...
    while(rowIndex >= dataColLinker.size()) {
        dataColLinker.add(value);
    } else {
        dataColLinker.set(rowIndex, value);
    }

有什么想法或理论吗? 当涉及到if 语句和ArrayList 命令等时,我不确定 java 的速度

【问题讨论】:

  • 所以你想添加相同的值N次然后你想将rowIndex更改为值?

标签: java performance arraylist while-loop theory


【解决方案1】:

我错过了什么吗?

这不是假设的代码

while(rowIndex >= dataColLinker.size()) {
    dataColLinker.add(value);
} else {
    dataColLinker.set(rowIndex, value);
}

和这个意思一样吗?

while(rowIndex >= dataColLinker.size()) {
    dataColLinker.add(value);
}
dataColLinker.set(rowIndex, value);

还是这个?

if (rowIndex >= dataColLinker.size()) {
    do {
        dataColLinker.add(value);
    } while(rowIndex >= dataColLinker.size());
} else {
    dataColLinker.set(rowIndex, value);
}

(后者更有意义......我猜)。无论哪种方式,很明显你可以重写循环,这样“else test”就不会在循环内重复......就像我刚刚做的那样。


FWIW,这很可能是过早优化的情况。也就是说,您可能在浪费时间优化不需要优化的代码:

  • 众所周知,JIT 编译器的优化器可能已经移动了代码,因此“else”部分不再在循环中。

  • 即使没有,您尝试优化的特定事物也可能不是重大瓶颈……即使它可能被执行 600,000 次。

我的建议是暂时忘记这个问题。让程序运行起来。当它工作时,决定它是否运行得足够快。如果没有,则对其进行分析,并使用分析器输出来决定值得花时间优化的地方。

【讨论】:

  • @Stephen 我认为在像 Python 这样的语言中,只有在最初没有满足 while 条件时才会执行 else 块。我知道这是 Java,我们这里没有,但这可能是问题的根源。
  • @Stephen,是的,您的第一个示例就是我所拥有的,但我希望它以更少的访问权限执行,因为它会通过很多次,这里是通过add 并再次通过set .第二个示例看起来不错,但我可能知道何时添加和更改值,从而使其更好地简化......在单独的函数中。我不知道稀疏数组???基本上这个 col 是我的tableModel 的一部分并识别链接的行,你可能对解决它有不同的想法吗?
  • @xchiltonx - 我不会就此向您提供更多建议,因为我怀疑您正在浪费时间进行过早的优化。请参阅我的更新答案。
  • 斯蒂芬+1。试图优化这是浪费你的时间。如果有任何改进的方法,Java 会自己找到。
  • 在 Python 中,else 语句仅在循环正常退出时才执行,即不中断。这是一个小众功能,但它有它的用途。
【解决方案2】:

我不明白为什么有一段时间的封装......

使用

//Use the appropriate start and end...
for(int rowIndex = 0, e = 65536; i < e; ++i){        
    if(rowIndex >= dataColLinker.size()) {
         dataColLinker.add(value);
     } else {
        dataColLinker.set(rowIndex, value);
     }    
}

【讨论】:

  • 基于while - else 语句,它应该是break 作为else 代码块内的最后一句。
  • 基于原来的问题有一个 else 子句与 while 我不会试图争论这个事实,但是你很可能是正确的
  • 元素个数未知
  • 这并不重要...您可以将 i
【解决方案3】:

将“set”语句包装成“如果未设置则设置”并将其裸露在 while 循环之上。

您是对的,该语言并没有提供您正在寻找的正是该语法的内容,但那是因为有像我刚才建议的那样的编程范例,所以您不需要您提出的语法。

【讨论】:

    【解决方案4】:
    boolean entered = false, last;
    while (( entered |= last = ( condition ) )) {
            // Do while
    } if ( !entered ) {
            // Else
    }
    

    不客气。

    【讨论】:

    • 这是一个非常神秘的答案。你能解释一下这里的逻辑并展示问题中代码的样子吗?尽管在同一个语句中有多个(非平凡的)赋值(不要介意循环条件),但对我来说,这表明你做错了。
    • 首先为 'whiled' 或输入的调用变量在这里可能更清楚。
    • @Dukeling 我正在以我在 Java 中看到的唯一可能的方式回答这个问题,没有冗余代码进行检查或提取到调用方法以检查重新检查条件。无论如何,原则基本上是始终检查并设置 last 条件,这是进入 while 循环实际需要为真的条件。然后你输入了 |= ... 这是一个与“输入”自我的 OR,所以最后的任何时候,或者条件为真,无论是在第一次检查还是后续检查,输入将始终为真,然后在 if 块中检查之后。
    【解决方案5】:

    Java 没有这种控制结构。
    但应该注意的是,其他语言也可以。
    例如,Python 具有 while-else 构造。

    在 Java 的例子中,你可以模仿你已经展示过的这种行为:

    if (rowIndex >= dataColLinker.size()) {
        do {
            dataColLinker.add(value);
        } while(rowIndex >= dataColLinker.size());
    } else {
        dataColLinker.set(rowIndex, value);
    }
    

    【讨论】:

      【解决方案6】:

      这个 while else 语句应该只在条件为 false 时执行 else 代码,这意味着它会一直执行它。但是,有一个问题,当你在 while 循环中使用 break 关键字时,else 语句不应该执行。

      满足does条件的代码只有:

      boolean entered = false;
      while (condition) {
         entered = true; // Set it to true stright away
         // While loop code
      
      
         // If you want to break out of this loop
         if (condition) {
            entered = false;
            break;
         }
      } if (!entered) {
         // else code
      }
      

      【讨论】:

      • 如果我或某人编写一个 while-else-loop 对象可能会更好:D
      【解决方案7】:

      假设您来自 Python 并接受这一点:

      def setLinkerAt(value, rowIndex):
          isEnough = lambda i: return i < dataColLinker.count()
          while (not isEnough(rowIndex)):
              dataColLinker.append(value)
          else:
              dataColLinker[rowIndex] = value 
      

      我能想到的最相似的是:

      public void setLinkerAt( int value, int rowIndex) {
          isEnough = (i) -> { return i < dataColLine.size; }
          if(isEnough()){
              dataColLinker.set(rowIndex, value);
          }
          else while(!isEnough(rowInex)) {
              dataColLinker.add(value);
          }
      

      注意逻辑和逆向逻辑的需要。我不确定这是一个很好的解决方案(逻辑重复),但无括号 else 是我能想到的最接近的语法,同时保持不执行超出要求的逻辑的相同行为。

      【讨论】:

        猜你喜欢
        • 2014-01-21
        • 1970-01-01
        • 1970-01-01
        • 2023-03-22
        • 2015-11-08
        • 1970-01-01
        • 2012-06-18
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多