最小化方法中的if条件

时间:2014-03-12 08:19:08

标签: java java-ee if-statement

我有以下课程。

public enum EnumService
{
    ONE, TWO, THREE, FOUR,.............HUNDRED;
    //Values till HUNDRED

    public static EnumService returnMockService(String request)
    {
        //some string match
        if(request.matches("/abc*")){
           return ONE;
        } 
        //some other string is match      
        else if(request.matches("/bcd*"))
            return TWO;
        else if(request.matches("/decf*"))
            return THREE;
        //many else if conditions
        else if(request.matches("/wxyz*"))
            return HUNDRED;
        return null;     

    }


}

代码不是更多if else语句的标准。

我想最小化上述方法中if调用的次数,同时将返回类型保持为EnumService

更好的选择。

如果有人可以帮助我保持干净,那就太棒了。

5 个答案:

答案 0 :(得分:5)

首先:如果你else,则无需return

第二:如果你在枚举中使用这个字符串作为参数,你可以优化它:

public enum EnumService
{
    ONE("abc*"),
    // etc

    private static final Map<Pattern, EnumService> MAPPING
        = new HashMap<>();

    static {
        for (final EnumService svc: values())
            MAPPING.put(svc.pattern, svc);
    }

    private final Pattern pattern;

    EnumService(final String s)
    {
        pattern = Pattern.compile(s);
    }

    public static EnumService returnMockService(String request)
    {
        for (final Map.Entry<Pattern, EnumService> entry: MAPPING.entrySet())
            if (entry.getKey().matcher(request).matches())
                return entry.getValue();
        return null;
    }
}

答案 1 :(得分:3)

我会将你匹配的字符串与他们应该映射到的EnumService值放到一个简单对象数组中,然后循环遍历数组。

E.g:

ArrayEntry[] entries = new ArrayEntry[] {
    new ArrayEntry("/abc*", EnumService.ONE),
    // ...and so on...
};

然后:

for (ArrayEntry entry : entries) {
    if (request.matches(entry.str)) {
        return entry.value;
    }
}
return null;

...其中ArrayEntry只是一个包含这两个属性的简单类(strvalue)。

如果您不想ArrayEntry,可以使用Map

Map<String,EnumService> entries = new HashMap<String,EnumService>();
entries.put("/abc*", EnumService.ONE);
//...and so on...

然后

for (Map.Entry<String,EnumService> entry : entries.entrySet()) {
    if (request.matches(entry.getKey())) {
        return entry.getValue();
    }
}
return null;

或者你可以用并行数组代替它:

String[] strings = new String[] { "/abc*", /*...and so on...*/ };
EnumService[] values = new EnumService[] { EnumService.ONE, /*...and so on...*/ };

然后

int n;
for (n = 0; n < strings.length; ++n) {
    if (request.matches(strings[n])) {
        return values[n];
    }
}
return null;

但并行阵列往往是一个维护问题。

答案 2 :(得分:1)

你可以去寻找设计模式,最好是这些东西都是状态模式。状态模式是解决这类问题并使代码更兼容&amp;灵活。
查看http://www.javacodegeeks.com/2013/08/state-design-pattern-in-java-example-tutorial.html

答案 3 :(得分:0)

如果没有将/abc映射到ONE和/bcdTWO等的逻辑,那么您可能需要将这些加载到数组或映射中,然后只需获取索引匹配的数组。

myMap.put("abc", ONE);
myMap.put("bcd", TWO);

答案 4 :(得分:0)

请查看以下链接。

Why can't I switch on a String?

如前所述,如果您使用的是jdk 7,只需在字符串上使用开关即可。如果没有,请创建/abc*/bcd*等枚举。并在开关中使用它们。

希望这有帮助。

或者你可以随时将它们存储在一个数组中并循环遍历它们。这将更容易,但需要额外的阵列。