kimsanity
kimsanity

Reputation: 17

possible refactor? long repeating lines of codes java

Hiii. So I have these really long switch-case, and I have these codes:

case 34:
            if(cToken.getName() == TokenName.PROG_NAME.toString() 
                || cToken.getName() == "DEDENT"
                || cToken.getName() == TokenName.ASSIGN.toString()
                || cToken.getName() == TokenName.PROC_CALL.toString()
                || cToken.getName() == TokenName.BREAK.toString()
                || cToken.getName() == TokenName.CONTINUE.toString()
                || cToken.getName() == TokenName.DATATYPE_BOOL.toString()
                || cToken.getName() == TokenName.DATATYPE_CHAR.toString()
                || cToken.getName() == TokenName.DATATYPE_FLOAT.toString()
                || cToken.getName() == TokenName.DATATYPE_INT.toString()
                || cToken.getName() == TokenName.DATATYPE_STRING.toString()
                || cToken.getName() == TokenName.DATATYPE_VOID.toString()
                || cToken.getName() == TokenName.INPUT.toString()
                || cToken.getName() == TokenName.OUTPUT.toString()
                || cToken.getName() == TokenName.IF.toString()
                || cToken.getName() == TokenName.DO.toString()
                || cToken.getName() == TokenName.WHILE.toString()
                || cToken.getName() == TokenName.INC_OP.toString()
                || cToken.getName() == TokenName.DEC_OP.toString()){
                    reduce(51);
            } else {
                error();
            } break;
case 35:
            if(cToken.getName() == TokenName.PROG_NAME.toString() 
                || cToken.getName() == "DEDENT"
                || cToken.getName() == TokenName.ASSIGN.toString()
                || cToken.getName() == TokenName.PROC_CALL.toString()
                || cToken.getName() == TokenName.BREAK.toString()
                || cToken.getName() == TokenName.CONTINUE.toString()
                || cToken.getName() == TokenName.DATATYPE_BOOL.toString()
                || cToken.getName() == TokenName.DATATYPE_CHAR.toString()
                || cToken.getName() == TokenName.DATATYPE_FLOAT.toString()
                || cToken.getName() == TokenName.DATATYPE_INT.toString()
                || cToken.getName() == TokenName.DATATYPE_STRING.toString()
                || cToken.getName() == TokenName.DATATYPE_VOID.toString()
                || cToken.getName() == TokenName.INPUT.toString()
                || cToken.getName() == TokenName.OUTPUT.toString()
                || cToken.getName() == TokenName.IF.toString()
                || cToken.getName() == TokenName.DO.toString()
                || cToken.getName() == TokenName.WHILE.toString()
                || cToken.getName() == TokenName.INC_OP.toString()
                || cToken.getName() == TokenName.DEC_OP.toString()){
                    reduce(52);
            } else {
                error();
            } break;

ok, so that's just two of the cases I have. I was just wondering if there's a way where I can make/use a shortcut for that long expression (which repeats) but because I use them in different cases, with different -to do- (if it passes the 'if' test e.g (case 34, call reduce method with 51 as input and case 35, call reduce method with 52 as input)

Basically, what I'm askin is if there's a way where I could like put

cToken.getName() == TokenName.PROG_NAME.toString() 
|| cToken.getName() == "DEDENT"
|| cToken.getName() == TokenName.ASSIGN.toString()
|| cToken.getName() == TokenName.PROC_CALL.toString()
|| cToken.getName() == TokenName.BREAK.toString()
|| cToken.getName() == TokenName.CONTINUE.toString()
|| cToken.getName() == TokenName.DATATYPE_BOOL.toString()
|| cToken.getName() == TokenName.DATATYPE_CHAR.toString()
|| cToken.getName() == TokenName.DATATYPE_FLOAT.toString()
|| cToken.getName() == TokenName.DATATYPE_INT.toString()
|| cToken.getName() == TokenName.DATATYPE_STRING.toString()
|| cToken.getName() == TokenName.DATATYPE_VOID.toString()
|| cToken.getName() == TokenName.INPUT.toString()
|| cToken.getName() == TokenName.OUTPUT.toString()
|| cToken.getName() == TokenName.IF.toString()
|| cToken.getName() == TokenName.DO.toString()
|| cToken.getName() == TokenName.WHILE.toString()
|| cToken.getName() == TokenName.INC_OP.toString()
|| cToken.getName() == TokenName.DEC_OP.toString()

to a variable or some placeholder and then use that variable in the if-clause so that long block of code only appears once, and then I'm just gonna use the variable that contains that?

Sorry if I can't explain better.. Thank you!

Upvotes: 0

Views: 73

Answers (4)

Carl Manaster
Carl Manaster

Reputation: 40336

Could you add a method getReductionFactor() to your TokenName class? Then just call

reduce(value + cToken.getReductionFactor());

and be done with it.

Upvotes: 0

Roland Weisleder
Roland Weisleder

Reputation: 10511

You could create a List with acceptable tokens

List<String> tokens = Arrays.asList(TokenName.PROG_NAME.toString(), "DECENT", ...);

and then check with

tokens.contains(cToken.getName())

Upvotes: 0

rgettman
rgettman

Reputation: 178263

It appears that the value passed to reduce is 17 more than the case label.

You can make sure that the value you're switching on is within the range you need, then pass value + 17 to reduce.

if (value >= x && value <= y)
{
     if (/* really long conditions here */)
     {
         reduce(value + 17);
     }
}

If there isn't a mathematical relationship between the case label and the value passed to reduce (and the "plus 17" was just a coincidence for the 2 cases you showed), then create a Map<Integer, Integer> of case labels to reduce values to be used when calling reduce.

That will eliminate the need to copy the long if conditions over and over again for each case.

Second, place all possible values for getName() in a List<String> and call contains to see if it matches one of them.

     if (listOfValues.contains(cToken.getName()) {

Upvotes: 1

Hovercraft Full Of Eels
Hovercraft Full Of Eels

Reputation: 285403

Consider putting your Strings in a collection such as an ArrayList or HashSet, and then seeing if the String of interest is contained in the collection via the contains(String) method.

As a side recommendation, don't compare Strings using == or !=. Use the equals(...) or the equalsIgnoreCase(...) method instead. Understand that == checks if the two object references are the same which is not what you're interested in. The methods on the other hand check if the two Strings have the same characters in the same order, and that's what matters here.

Upvotes: 2

Related Questions