Search code examples
javasonarqubecode-duplication

How to solve multiple "if return" statements being reported as duplicated code by sonarqube


Sonarqube reports duplicate code when having multiple if return statements. For example I have the following code:

private static double computeGain(int rangeMax) {
        if (rangeMax <= 35) {
            return 6.0;
        } else if (rangeMax <= 85) {
            return 5.0;
        } else if (rangeMax <= 170) {
            return 4.0;
        } else if (rangeMax <= 340) {
            return 3.0;
        } else if (rangeMax <= 850) {
            return 2.0;
        } else if (rangeMax <= 1700) {
            return 1.0;
        } else if (rangeMax <= 3400) {
            return 0.5;
        } else if (rangeMax <= 8000) {
            return 0.25;
        }

        return 0.0D;
    }

I've tried replacing the return by an assignment to a variable like this gain = 6.0;, to reduce the number of return to no avail.

Removing all the else, since they are superfluous, didn't work either.


Solution

  • regarding to jfpatenaude answer, it's good solution but it is better to keep range and gains together (combined to one object) instead of keeping it in two tables

    static private class RangeGainPair {
            int range;
            double gain;
    
            public RangeGainPair(int range, double gain) {
                this.range = range;
                this.gain = gain;
            }
    
            public int getRange() {
                return range;
            }
    
            public double getGain() {
                return gain;
            }
        }
    
        private static List<RangeGainPair> rangeGainList = Stream.of(new RangeGainPair(35, 6d),
                        new RangeGainPair(85, 5d),
                        new RangeGainPair(170, 4d),
                        new RangeGainPair(340, 3d),
                        new RangeGainPair(850, 2d),
                        new RangeGainPair(1700, 1d),
                        new RangeGainPair(3400, 0.5d),
                        new RangeGainPair(8000, 0.25d))
                .collect(Collectors.toList());
    
        private static double computeGain(int rangeMax) {
            return rangeGainList.stream().filter(rangeGainPair -> rangeMax <= rangeGainPair.range).findFirst()
                    .map(RangeGainPair::getGain).orElse(0d);
        }
    

    In this case if you add new value to range, it will be easier to add proper value for gain (eg. you don't need to count commas if you want to add range 500 and 2.5 gain) and the more entries you have, the more difficult it gets to do this in jfpatenaude answer.

    You can also use table like jfpatenaude was (e.g because you don't like streams or don't know them, or use lower java version), but one, not two.

    Because it is constant values, it good for performance reason to build list (or table) only once, so outside of the function.