【问题标题】:Break while loop only when all conditions in for loop are met仅当满足 for 循环中的所有条件时才中断 while 循环
【发布时间】:2019-04-02 16:54:04
【问题描述】:

只有当所有“机器人”都直立时,我才想打破while 循环。 (*这些机器人是指迷你 USB 机器人)。

.upRight() 在机器人站立时返回 true,在机器人不站立时返回 false

public static boolean checkSomething() throws ... {

        while (true) {

            for (i = 0; i < bots; i++) { // bots = 2
                if (!theMainBots[i].isUpright()) {
                    ...
                    Thread.sleep(1000); 
                } 
                else {
                    return true;

                }
            }
        }

我面临的问题是,如果 isUpright() 方法对第一个“机器人”返回 true,那么所有其他机器人都不会被选中,并且可能会返回 false。目的是等待用户将机器人放置在直立位置,然后再继续。

【问题讨论】:

  • 为什么是while(true)
  • @ernest_k 抱歉,我对 Java 很陌生。这样做有什么问题?
  • 仅供参考: OP has said: “机器人很可能再次摔倒。”

标签: java for-loop while-loop break


【解决方案1】:

你可以从机器人数组创建一个列表,使用迭代器迭代这个列表 如果一个特定的机器人是直立的,使用 iterator.remove 从这个列表中删除它。 外部 while 将一直运行,直到列表不为空。

public static boolean checkUpright()  {
    ArrayList<Bot> notUprightBots=   (ArrayList<Bot>) Arrays.asList(theBots);
    while (!notUprightBots.isEmpty()) {
        Iterator<Bot> iterator=notUprightBots.iterator();
        while(iterator.hasNext()){
            Bot bot=iterator.next();
            if (!bot.isUpright()) {
                System.out.println("Please ensure I'm upright");
                try{
                     Thread.sleep(500); 
                 }catch(InterruptedException  e){
                 } 

            }else {
                iterator.remove();
            }
        }
    }
    return true;

}

【讨论】:

    【解决方案2】:

    您应该先检查所有机器人,然后根据结果采取行动。不要试图对检查循环内的结果采取行动。

    此外,由于在所有机器人都直立之前代码不会返回,因此该方法命名错误并且不应返回值。

    public static void waitUntilAllUpright() throws InterruptedException {
        for (;;) { // forever loop
            boolean allUpright = true;
            for (i = 0; i < bots; i++) {
                if (! theBots[i].isUpright()) {
                    allUpright = false;
                    break;
                } 
            }
            if (allUpright)
                return;
            System.out.println("Please ensure I'm upright");
            Thread.sleep(500); 
        } // loop back to check all bots again
    }
    

    【讨论】:

      【解决方案3】:

      上下文并不完全清楚,但将逻辑控制与用户交互混合可能是问题所在。也许这种方法可能有效:

      public static boolean checkUpright() throws InterruptedException {
          while (!areAllBotsUpright()) {
              System.out.println("Please ensure I'm upright");
              Thread.sleep(500);
          }
      }
      
      public static boolean areAllBotsUpright() {
         for (i = 0; i < bots; i++) {
             if (!theBots[i].isUpright()) {
                 return false;     
             } 
         }
      
         return true;
      }
      

      【讨论】:

        【解决方案4】:

        实现此目的的一种方法是使用一个变量来确定何时离开循环。您的问题是,您还需要将for 循环更改为while 循环。这是为什么?因为您不知道您刚刚检查的机器人是否被移动。此外,外循环是不必要的,除非您想再次检查。所以代码最终看起来像这样。

        public static boolean checkUpright() throws InterruptedException {
        
            int counter = 0;
            while (counter <= theBots.length) { // bots = 2
                if (!theBots[i].isUpright()) {
                    System.out.println("Please ensure I'm upright");
                    Thread.sleep(500); 
                } else {
                    counter ++;
                }
            }
        }
        

        【讨论】:

          【解决方案5】:

          如果您想等到用户让机器人直立,您可以将if 更改为while

          while (true) {
               for (i = 0; i < bots; i++) { // bots = 2
                   while(!theBots[i].isUpright()) {
                       System.out.println("Please ensure I'm upright");
                       Thread.sleep(500); 
                   } 
               }               
               return true;     
          }
          

          这将循环遍历Array 中的每个元素,并且当任何给定的机器人不直立时,它将循环并休眠,直到机器人转直为止。这种情况下不需要while(true)循环:

          public static boolean checkUpright() throws InterruptedException {
                for (i = 0; i < bots; i++) { // bots = 2
                   while(!theBots[i].isUpright()) {
                       System.out.println("Please ensure I'm upright");
                       Thread.sleep(500); 
                   } 
               }               
               return true;    
          }
          

          【讨论】:

          • 你可以摆脱外部的while循环
          • @DaneWhite 正确。我已经在进行编辑了。感谢您指出这一点
          • 如果没有更详细的说明,如果isUpright() 可以随着时间从false 转换为true,那么它也可以转换为其他方式是可行的,所以当你到达最后一个机器人,第一个机器人可能又掉了。不涉及并发问题,您可能应该在等待后重新启动检查。
          • @Andreas 确实如此。机器人再次摔倒的可能性更大。
          • @GBlodgett 谢谢。正是我想要的。现在有效! :)
          猜你喜欢
          • 1970-01-01
          • 2017-08-01
          • 1970-01-01
          • 1970-01-01
          • 2023-01-12
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多