减少 Java 中的 if-else 语句

Posted

技术标签:

【中文标题】减少 Java 中的 if-else 语句【英文标题】:Reducing if-else statements in Java 【发布时间】:2012-05-11 17:58:46 【问题描述】:

我有以下代码:

void f(String t)

  if(t.equals("a"))
  
    someObject.setType(ObjectType.TYPE_A);
  
 else if(t.equals("b"))
  
    someObject.setType(ObjectType.TYPE_B);
  

// 50 more similar code


有没有什么简单的方法可以重写 if-else 条件,以免有那么多代码?

【问题讨论】:

【参考方案1】:

你应该使用一些东西来消除someObject.setType(ObjectType....)) 的重复如果ObjectTypeenum,那么在那里编写一个类似于valueOf 的方法来实现这一点。看看你是否喜欢这种解决方案:

void f(String t)  someObject.setType(ObjectType.byName(t)); 

enum ObjectType 
  TYPE_A, TYPE_B;
  public static ObjectType byName(String name) 
    return valueOf("TYPE_" + name.toUpperCase());
  

【讨论】:

不是吹毛求疵,你只需要小心这里的异常处理;您必须将返回值包装在 try-catch 块中,以处理垃圾输入场景。 @questzen 好吧,这只是基本大纲。根据愿望,有多种处理垃圾的方法。我个人通常更喜欢原始异常(如果传递垃圾确实是一个错误)。这为您提供了最直接的调试信息。【参考方案2】:

使用从String 映射到ObjectType.TYPE_x 值的任何类型的Map(您必须填充)。

【讨论】:

是的,我也是这么想的。但我唯一怀疑的是存储这些字符串所需的内存以及获取类型所需的查找。没有别的办法吗? @Asha 地图中的字符串(因为它们是被实习的)不会比字符串文字占用更多的空间。查找时间将减少,因为地图查找将是 O(log n) 而不是 O(n) @Alnitak 使用HashMap 甚至可以访问O(1) @Asha 如果您使用枚举,则不必显式管理地图。请参阅我的更新答案。 @Mudu 是的,这将是在这种情况下使用的一个很好的(具体)实现。【参考方案3】:

我会将其添加为枚举的功能:

public enum ObjectType 
    TYPE_A("a"),
    TYPE_B("b");

    private String stringType;

    private ObjectType(String stringType) 
        this.stringType = stringType;
    

    public String getStringType() 
        return this.stringType;
    

    public static ObjectType fromStringType(String s) 
        for (ObjectType type : ObjectType.values()) 
            if (type.stringType.equals(s)) 
                return type;
            
        
        throw new IllegalArgumentException("No ObjectType with stringType " + s);
    


...

void f(String t) 
    someObject.setType(ObjectType.fromStringType(t));

【讨论】:

这是我常用的方法。比依赖常量名更好,因为它更灵活,更难破解。【参考方案4】:

如果您可以将t 重构为char,则可以改用switch (Java 6):

void f(char t) 

  switch(t) 

    case 'a`:
      someObject.setType(ObjectType.TYPE_A);
      break;
    case 'b':
      someObject.setType(ObjectType.TYPE_B);
      break;

    // ...

  


正如 Marko 所指出的,您也可以在 Java 7 中使用 String

它并没有那么短,但更优雅。此外,我认为它也可能更快,因为switch 与跳转表接近O(1)(有人可以确认这是否属实吗?),if 语句的数量是否为O(n)

对于比单个setType 更复杂的实现,您可能还会想到State Pattern 实现。

【讨论】:

【参考方案5】:

1.如果if条件数超过3个,可以选择switch语句。

2.您可以将 if else 语句转换为ternary operations

【讨论】:

【参考方案6】:

其他建议很棒——尤其是更智能的枚举和映射。但是我在这里要解决的第一个最基本的重构是提取一个方法来直接返回枚举,并让调用者只对该方法的返回值执行 setType。

void f(String t) 
  final ObjectType type = findType(t);
  if (type != null)
    someObject.setType(type);
  

ObjectType findType(String t) 
  if (t.equals("a")) return ObjectType.TYPE_A;
  if (t.equals("b")) return ObjectType.TYPE_B;
  // 50 more similar code
  

在某些情况下,这本身就足够了;在其他情况下,findType() 方法可能会引导您使用基于映射或枚举的简单解决方案。

【讨论】:

以上是关于减少 Java 中的 if-else 语句的主要内容,如果未能解决你的问题,请参考以下文章

可以一学的代码优化小技巧:减少if-else冗余

有啥方法可以减少程序中条件语句if-else或者switch-case的过多嵌套?

可以一学的代码优化小技巧:减少if-else冗余

可以一学的代码优化小技巧:减少if-else冗余

“全栈2019”Java第二十二章:控制流程语句中的决策语句if-else

Java中条件语句和if-else的嵌套原则