【问题标题】:Skip if conditions when a flag is false标志为假时跳过条件
【发布时间】:2017-08-09 04:05:43
【问题描述】:

我有几个独立的 if 条件,在每个条件下我都会评估一个布尔变量值,无论是真还是假。

如果布尔变量值在第一个 if 条件中为 false,那么我如何跳过所有条件的其余部分。

private static boolean isRecommended(Fruit fruit) {
    boolean isRecommended = true;

    if(fruit.weight > 2){
        isRecommended = false;
    }
    if(!"red".equals(fruit.color)){
        isRecommended = false;
    }
    if(!"sweet".equals(fruit.taste)){
        isRecommended = false;
    }
    if(!fruit.isPerishable){
        isRecommended = false;
    }

    return isRecommended;
}

如果执行了第一个 if() 条件,那么是否可以返回该值。我知道在循环中我们可以使用continue 关键字来跳过循环执行的其余部分。我们怎样才能在这里实现类似的东西。

更新:

我并不是指第一个 if() 条件,如果执行了任何 if() 条件,那么像 continue 在循环中那样跳过其余条件的最佳方法是什么

【问题讨论】:

  • 为什么不使用 if-else if - else 构造?
  • 从那个扩展你的括号,以防错误的使用 break 语句。
  • 摆脱你的 isRecommended 并从你的 ifs 中返回 false。
  • 为什么要跳过其余的条件?是因为您有需要消除的性能瓶颈,还是有时会得到错误的结果?
  • 对不起,我的意思不是完全在第一个 if() 条件下,如果执行了任何 if() 条件,那么像 continue 在循环中那样跳过其余条件的最佳方法是什么

标签: java


【解决方案1】:
return fruit.weight <= 2 
    && "red".equals(fruit.color) 
    && "sweet".equals(fruit.taste)
    && fruit.isPerishable;

【讨论】:

    【解决方案2】:

    对于一般解决方案,您可以使用else if

    if(fruit.weight > 2){
        isRecommended = false;
    }
    else if(!"red".equals(fruit.color)){
       //etc...
    }
    

    但在您的具体示例中,您可以只使用布尔逻辑:

    return !(
       fruit.weight > 2 ||
       !"red".equals(fruit.color) ||
       !"sweet".equals(fruit.taste) ||
       !fruit.isPerishable
    );
    

    您可以使用您的 IDE 通过应用De Morgan's laws 重构此表达式的逻辑。大多数体面的 IDE 只需几次击键即可为您完成此操作。

    【讨论】:

    • 你可以 De Morgan 那个布尔逻辑; IMO 这样看起来很混乱。
    • 你可以这样做,但你可能会像this guy did那样弄错。人类不是为在头脑中进行德摩根逻辑而设计的。以最合乎逻辑的方式编写它(在 OP 看来)然后让您的 IDE 为您执行 De Morgan 反转
    • @dystroy:我并不是说您的版本可读性较差。我的意思是,当 IDE 具有自动为您执行此操作且永远不会出错的功能时,人类不应该进行 De Morgan 转换。
    • @dystroy FWIW AmitD 也弄错了,但是在我发表评论之后/之后修复了它。所以马克可能有一点。
    • @MarkByers 你说得对,我们不应该进行这种转换。但我的解决方案不是让 IDE 来做,而是回到本意。对我来说,编码速度与阅读/修复/维护的速度(个人意见)相比,相关性要小得多。
    【解决方案3】:

    您可以像这样压缩它,通过使用多个返回语句,这些语句将提前返回并跳过其余部分。为了更加简洁,我还删除了不需要的花括号。

    private static boolean isRecommended(Fruit fruit) {
        if(fruit.weight > 2)
            return false;
        if(!"red".equals(fruit.color))
            return false;
        if(!"sweet".equals(fruit.taste))
            return false;
        if(!fruit.isPerishable)
            return false;
        return true;
    }
    

    【讨论】:

    • 我不喜欢删除“不需要的”花括号。如果将来有人决定在这些返回之一之前添加一条语句(例如:日志)怎么办?不会产生语法错误(尽管它可能会抱怨死代码),现在你手头一团糟。
    • @NullUserException:我同意,不是每个人都是。我曾经反对它,但我发现它使它更具可读性,因为它更小并且不会使它更容易引入错误。此外,Robert Martin 在他的《清洁代码》一书中也主张消除不必要的卷曲。并不是说我在所有事情上都同意他,但我同意。
    • 对我来说,这不是它是否更容易出错,而是 IDE 的自动格式化无论如何都会破坏大括号格式;并且一致的自动格式化有利于版本控制。
    • @JohanSjöberg 我使用 NetBeans,但还没有看到它的自动格式化毁了我的牙套。但后来我将自己的风格调整为 Sun/Oracle 建议的风格,我认为这是 NetBeans 在其自动格式化中使用的风格。
    【解决方案4】:

    如果执行了第一个 if() 条件,那么是否可以返回 价值。

    不就是这样吗?

    if(fruit.weight > 2){
        return false; // etc.
    }
    

    还是我误解了你的问题?

    【讨论】:

    • 对不起,我的意思不是完全在第一个 if() 条件上,如果执行了任何 if() 条件,那么跳过像 continue 这样的其余条件的最佳方法是循环
    • 啊,我想你会根据我的建议推断罗伯特·汉森的回答 (stackoverflow.com/a/12752626/58668)。一般答案:使用任何适合该任务的控制流运算符。另一种解决方案是do { ... } while (0),当你有答案时再break;第三种解决方案是使用异常。不过,对于手头的问题,两者都过大了,所以我会选择基于回报的问题。
    【解决方案5】:

    测试将在第一次未验证时停止。

    private static boolean isRecommended(Fruit fruit) {
        return 
                fruit.weight <= 2
                && "red".equals(fruit.color)
                && "sweet".equals(fruit.taste)
                && fruit.isPerishable
        ;
    }
    

    【讨论】:

      【解决方案6】:

      你可以写

      return isRecommended;
      

      在你的 ifs 中。 return 可以多次使用。

      【讨论】:

      • 编译时错误“此方法必须返回布尔类型的结果”
      • @KaipaMSarma.. 在所有 if- 块的末尾,您需要返回一个值 .. return true.. 即当前将您的 return isRecommended 替换为 return true
      【解决方案7】:

      简单的答案是在if 块内return,而不是设置一个值。但是,这并不是完全可扩展的,并且块内的returning 会增加代码复杂性。

      复杂但更灵活的答案是创建一个interface,允许您实现自定义逻辑。

      interface RecommendationFilter<T>
      {
          boolean recommend(T item);
      }
      

      然后,在某些实现中,可以使用一堆一般加载的RecommendationFilters 来循环。

      class FruitChecker
      {
          private final Set<RecommendationFilter<Fruit>> filters = ...;
      
          public boolean isRecommended(Fruit fruit)
          {
              boolean recommended = true;
      
              for (RecommendationFilter<Fruit> filter : filters)
              {
                  if ( ! filter.recommend(fruit))
                  {
                      recommended = false;
                      break;
                  }
              }
      
              return recommended;
          }
      }
      

      这个想法可以很好地扩展,并且可以实现一些非常有趣的实现。

      【讨论】:

        【解决方案8】:

        只需在您的第一个条件中添加return false

        【讨论】:

          【解决方案9】:

          将其余的 if 语句包装在 else 语句中:

          private static boolean isRecommended(Fruit fruit) {
              boolean isRecommended = true;
          
              if(fruit.weight > 2){
                  isRecommended = false;
              } else {
                  if(!"red".equals(fruit.color)){
                      isRecommended = false;
                  }
                  if(!"sweet".equals(fruit.taste)){
                      isRecommended = false;
                  }
                  if(!fruit.isPerishable){
                      isRecommended = false;
                  }
              }
          
              return isRecommended;
          }
          

          附言我强烈建议使用空格而不是制表符进行缩进。选项卡通常不会以您想要的方式移植到其他编辑器或环境。

          【讨论】:

            【解决方案10】:

            我找到了另一种解决方案,即使用带有 break 语句的标签块。下面是代码

            private static boolean isRecommended(Fruit fruit) {
                boolean isRecommended = true;
            
                labelA:
                {
                    if(fruit.weight > 2){
                        isRecommended = false;
                        break labelA;
                    }
                    if(!"red".equals(fruit.color)){
                        isRecommended = false;
                        break labelA;
                    }
                    if(!"sweet".equals(fruit.taste)){
                        isRecommended = false;
                        break labelA;
                    }
                    if(!fruit.isPerishable){
                        isRecommended = false;
                    }
                }
                return isRecommended;
            
            
            }
            

            【讨论】:

              【解决方案11】:
                  private static boolean isRecommended(Fruit fruit) {
                  while(true)
                  {
                    boolean isRecommended = true;
              
                    if(fruit.weight > 2){
                        isRecommended = false;
                        break;
                    }
                    if(!"red".equals(fruit.color)){
                        isRecommended = false;
                        break;
                    }
                    if(!"sweet".equals(fruit.taste)){
                        isRecommended = false;
                        break;
                    }
                    if(!fruit.isPerishable){
                        isRecommended = false;
                        break;
                    }
                  }
                  return isRecommended;
              }
              

              【讨论】:

              • 跳过所有后续 if 条件的最佳方法 :)
              • 如果你想在所有假期间避免无限循环..使用 int i = 0; while(i
              猜你喜欢
              • 2021-08-24
              • 1970-01-01
              • 1970-01-01
              • 2016-08-22
              • 2016-08-02
              • 1970-01-01
              • 1970-01-01
              • 2017-10-12
              • 2013-02-21
              相关资源
              最近更新 更多