【问题标题】:How to make this if statement more elegant in java?如何使这个 if 语句在 java 中更优雅?
【发布时间】:2020-12-08 07:56:11
【问题描述】:

在我的项目中,有类似如下代码的逻辑,会有多种类型,不过这样写太乱了,想问问有没有更优雅的方式.

int a = 3,b = 5;
int type = 2;
if (type == 1) {
    if (a > 1) {
        System.out.println("a > 1");
    } else if (b > 3) {
        System.out.println("b > 3");
    }
}
if (type == 2) {
    if (b > 3) {
        System.out.println("b > 3");
    } else if (a > 1) {
        System.out.println("a > 1");
    }
}

【问题讨论】:

  • 一个 switch 语句会稍微好一点。
  • 一个 switch 语句可能吗?很难在这段代码中挑选出特别适合重构以使其“优雅”的模式。请记住,“优雅”和“优化”通常是对立的目标。
  • 只有两个变量a 和b?
  • @Bohemian♦ 实际项目中if语句中的三个条件,a和b只是为了说明
  • 如果没有看到实际的代码(不是喜欢的实际代码),就很难给出重构的建议。这就像医生检查我姐姐看我是否健康。

标签: java if-statement optimization


【解决方案1】:

使用Map<Integer, BiConsumer<Integer, Integer>。

Map<Integer, BiConsumer<Integer, Integer> map = new HashMap<>();
map.put(1, (a, b) -> {
  if (a > 1) {
      System.out.println("a > 1");
  } else if (b > 3) {
      System.out.println("b > 3");
  }
});
map.put(2, (a, b) -> {
  if (b > 3) {
      System.out.println("b > 3");
  } else if (a > 1) {
      System.out.println("a > 1");
  }
});

然后使用:

Optional.ofNullable(map.get(type)).ifPresent(c -> c.accept(a, b));

【讨论】:

  • 这比 OP 的代码更好,因为……?
  • @Holger 因为地图可以在使用点的其他地方定义、填充和测试。人口甚至可以通过 spring bean,每个条件/lambda 对都是它自己的 bean。这是关于脱钩的。通过使用这种抽象,您可以更改地图的填充方式、时间和地点,为每个环境拥有自定义地图,维护和升级代码,并且它是可扩展的。如果您将其作为硬代码写入,您实际上无法执行任何这些操作。
  • 既然问题中没有说明这个动机,不应该在你的回答中而不是在评论中吗?
【解决方案2】:

所以你有一堆相关消息的条件,并且想要根据类型以不同的顺序检查它们?

如果是这样,你可以声明

interface Checker {
    String check();
}

然后做:

Checker ca = () -> a > 1 ? "a > 1" : null;
Checker cb = () -> b > 3 ? "b > 3" : null;

Checker[][] checkers = {
        null,
        {ca, cb},
        {cb, ca},
};

for (var checker : checkers[type]) {
    var message = checker.check();
    if (message != null) {
        return message;
    }
}
return null;

这对每个条件只定义一次,无论有多少类型。

(你也可以使用 switch 表达式而不是数组)

【讨论】:

    【解决方案3】:

    您可以尝试使用 switch 语句,它会使它更加优雅。 大致如下:

            int a = 3, b =  5;
            int type = 2;
    
            switch (type)
            {
                case 1:
                    if (a>1) System.out.println("a > 1");
                    else if (b > 3) System.out.println("b > 3");
                    break;
                
    
                case 2:
                    if(b > 3) System.out.println("b > 3");
                    else if(a > 1) System.out.println("a > 1");
                    break;
            }
    

    希望对你有所帮助,祝你好运!

    【讨论】:

    • 糟糕,我想你是对的。在过去的几天里,我正在试验 C 的 switch 语句,所以我有点搞混了。正在编辑,感谢您的评论。
    【解决方案4】:

    如果检查和操作是重复的,你可以通过这样的方式避免一些重复。 这样做的坏处是使用副作用...

    private boolean checkA(int a) {
    
        if (a > 1) {
           System.out.println("a > 1");
           return true;
        } 
        return false;
    }
    
    private boolean checkB(int b) {
    
        if (b > 3) {
           System.out.println("b > 3");
           return true;
        } 
        return false;
    }
    
    
    ...
    
    switch (type)
    {
         case 1: if (!checkA(a)) {
                      checkB(b);
                 }
                 break;
         case 2: if (!checkB(b)) {
                      checkA(a);
                 }
                 break;
    
    }
    

    编辑

    另一种可能被“滥用”的讨厌方式是

        boolean dummy;
        switch (type)
        {
             case 1: dummy = checkA(a) || checkB(b);
                     break;
             case 2: dummy = checkB(b) || checkA(a);
                     break;
    
        }
    

    【讨论】:

      【解决方案5】:

      从使用不同类型的类开始。这将使添加更多具有不同行为的类型变得更加容易。然后,您可以分别查看简化类。您还可以使用单元测试单独测试它们。

      你的例子变成了……

      new Type2(3, 5).process();
      

      如果你有以下课程

      public interface Processor {
          void process();
      }
      
      public class Type1 implements Processor {
      
          private int a;
          private int b;
          
          public Type1(int a, int b) {
              this.a = a;
              this.b = b;
          }
          
          @Override
          public void process() {
              if (a > 1) {
                  System.out.println("a > 1");
              } else if (b > 3) {
                  System.out.println("b > 3");
              }
          }
      
      }
      
       public class Type2 implements Processor {
      
          private int a;
          private int b;
          
          public Type2(int a, int b) {
              this.a = a;
              this.b = b;
          }
      
          @Override
          public void process() {
              if (b > 3) {
                  System.out.println("b > 3");
              } else if (a > 1) {
                  System.out.println("a > 1");
              }
          }
      
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-07-30
        • 1970-01-01
        • 1970-01-01
        • 2017-05-10
        相关资源
        最近更新 更多