Home > other >  How to fix SonarLint Cognitive Complexity Error for many If else condition
How to fix SonarLint Cognitive Complexity Error for many If else condition

Time:10-13

I have to write a lot of conditions but sonarlint is giving error to refactor the method to reduce its cognitive complexity. How to resolve this. I tried switch case but that is also giving the same error.

public enum ExampleEnum{
UNKNOWN(-1),
D0_D100(0),
D100_D200(100),
D200_D300(200),
D300_D400(300),
D400_D500(400),
D500_D600(500),
D600_D700(600),
D700_D800(700),
D800_D900(800),
D900_D1000(900);
public static ExampleEnum getScoreType(Integer score) {
    if (Objects.isNull(score) || score < D0_D100.score) {
        return UNKNOWN;
    } else if (score >= D0_D100.score && score < D100_D200.score) {
        return D0_D100;
    } else if (score >= D100_D200.score && score < D200_D300.score) {
        return D100_D200;
    } else if (score >= D200_D300.score && score < D300_D400.score) {
        return D200_D300;
    } else if (score >= D300_D400.score && score < D400_D500.score) {
        return D300_D400;
    } else if (score >= D400_D500.score && score < D500_D600.score) {
        return D400_D500;
    } else if (score >= D500_D600.score && score < D600_D700.score) {
        return D500_D600;
    } else if (score >= D600_D700.score && score < D700_D800.score) {
        return D600_D700;
    } else if (score >= D700_D800.score && score < D800_D900.score) {
        return D700_D800;
    } else if (score >= D800_D900.score && score < D900_D1000.score) {
        return D800_D900;
    } else {
        return D900_D1000;
    }
}

CodePudding user response:

Put the logic into a loop. something like:

public static ExampleEnum getScoreType(Integer score) {
    if (Objects.isNull(score) || score < D0_D100.score) {
        return UNKNOWN;
    for (int i =0; i< ExampleEnum.values().length-1;i  ) {
        if (ExampleEnum.values()[i].score <= score && ExampleEnum.values()[i 1].score > score )
            return ExampleEnum.values()[i];
    }
    return D900_D1000;
}

CodePudding user response:

You can use of the Stream API to remove this redundancy.

For that, you make use of the fact that the natural order of your enum-members reflects the order of the corresponding score.

As the source of the stream, you can use an array returned by the values() call or an EnumSet (which a specialized ordered collection) generated via EnumSet.allOf().

While iterating over the enum-members we need to find the first constant which score is equal or less to the given score. Because score property of your enum represent the lower boundary of the range, only one condition would be sufficient to find out if the given score falls into the range corresponding to a particular enum-member.

This logic can be expressed by using combination of operations filter() findFirst():

public static ExampleEnum getScoreType(Integer score) {
    if (score == null || score < ExampleEnum.D0_D100.score) {
        return ExampleEnum.UNKNOWN;
    }
    
    return EnumSet.allOf(ExampleEnum.class).stream()
        .filter(e -> score >= e.score)
        .findFirst()
        .orElse(ExampleEnum.D900_D1000);
}
  • Related