Java 如何降低其方法的认知复杂性?

Java 如何降低其方法的认知复杂性?,java,optimization,code-complexity,Java,Optimization,Code Complexity,我有一种把罗马数字转换成普通十进制的方法。我在这里使用了一个循环和很多“如果”条件。 IDE中的Sonaralint告诉我,这种方法的认知复杂度是33,而允许15。 我怎样才能减少这个?我不介意我如何解决这个问题。等待您的回复 public static int roman2Decimal(String roman) { int decimal = 0; char previous = 0; for (int x = 0; x < roma

我有一种把罗马数字转换成普通十进制的方法。我在这里使用了一个循环和很多“如果”条件。 IDE中的Sonaralint告诉我,这种方法的认知复杂度是33,而允许15。 我怎样才能减少这个?我不介意我如何解决这个问题。等待您的回复

public static int roman2Decimal(String roman) {
        int decimal = 0;
        char previous = 0;

        for (int x = 0; x < roman.length(); x++) {
            if (roman.charAt(x) == 'I')
                decimal += 1;

            if (roman.charAt(x) == 'V') {
                System.out.println(previous);
                if (previous == 'I') {
                    decimal -= 2;
                }
                decimal += 5;
            }

            if (roman.charAt(x) == 'X') {
                if (previous == 'I') {
                    decimal -= 2;
                }
                decimal += 10;
            }

            if (roman.charAt(x) == 'L') {
                if (previous == 'X') {
                    decimal -= 20;
                }
                decimal += 50;
            }

            if (roman.charAt(x) == 'C') {
                if (previous == 'X') {
                    decimal -= 20;
                }
                decimal += 100;
            }

            if (roman.charAt(x) == 'D') {
                if (previous == 'C') {
                    decimal -= 200;
                }
                decimal += 500;
            }

            if (roman.charAt(x) == 'M') {
                if (previous == 'C') {
                    decimal -= 200;
                }
                decimal += 1000;
            }
            previous = roman.charAt(x);
        }
        return decimal;
    }

公共静态int-roman2Decimal(字符串罗马){
整数小数=0;
char-previous=0;
对于(int x=0;x
开关大小写更适合此任务,因为只有一个选项是正确的,或者如果您想坚持使用“if”,则执行“if-else”,这样您就不需要检查所有选项,只需在找到正确的选项之前进行检查。

第一步是将重复的
if
语句替换为
开关:

公共静态int-roman2Decimal(字符串罗马){
整数小数=0;
char-previous=0;
对于(int x=0;x

如果我们进一步进行重构,我们可能会注意到其他重复的模式。使用枚举将有助于使此方法更加简洁:

枚举数字{
零(0,null),//哨兵
I(1,零),
V(5,I),
X(10,I),
L(50,X),
C(100,X),
D(500,C),
M(1000,C);
公共最终国际公司;
公众最终投票;
RomanDigit(国际公司,RomanDigit prev){
this.inc=inc;
this.prev=prev;
}
}
公共静态int-roma2decima2l(字符串罗马){
整数小数=0;
RomanDigit previous=RomanDigit.0;
for(char c:roman.toCharArray()){
RomanDigit电流=RomanDigit.valueOf(字符串.valueOf(c));
如果(上一个等于(当前上一个)){
十进制-=2*previous.inc;
}
十进制+=当前有限公司;
先前=当前;
}
返回小数;
}

认知复杂性与方法长度或逻辑分支嵌套(if语句)有关。对于
roman.charAt(x)
表达式,最好使用
开关。至少