Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Efficiently Check Multiple Conditions [closed]

I've got a situation in which I need to check multiple conditions, where every combination has a different outcome. In my specific condition, I've got 2 variables, which are enum types, that can each be 2 different values.

enum Enum1
{
    COND_1,
    COND_2
}
enum EnumA
{
    COND_A,
    COND_B
}
Enum1 var1;
EnumA varA;

This gives me 4 possible conditions, which requires 4 different outcomes. I've come up with a few different ways of doing this, either using if statements or switch statements:

if(var1 == Enum1.COND_1 && varA == EnumA.COND_A)
{
    // Code
}
else if(var1 == Enum1.COND_1 && varA == EnumA.COND_B)
{
    // Code
}
else if(var1 == Enum1.COND_2 && varA == EnumA.COND_A)
{
    // Code
}
else if(var1 == Enum1.COND_2 && varA == EnumA.COND_B)
{
    // Code
}

Or:

switch(var1)
{
    case COND_1:
        switch(varA)
        {
            case COND_A:
                // Code
                break;
            case COND_B:
                // Code
                break;
        }
        break;
    case COND_2:
        switch(varA)
        {
            case COND_A:
                // Code
                break;
            case COND_B:
                // Code
                break;
        }
        break;
}

I've thought of others, but don't want to fill this up with code :P I'd like to know what the best way to do this is. I think the switch is a bit easier to read, but the ifs are shorter. I think it'd be really cool if switches could have multiple conditions, but I haven't heard of it. This also begs the question: what's the best way to do this with an arbitrary number of variables and possible values?

like image 216
Fromen Avatar asked Nov 29 '16 07:11

Fromen


Video Answer


1 Answers

For your small use case I would probably go for nested if statements. But if you have plenty of enum constants, perhaps a pattern using streams could make your code easier to read and maintain (for a small performance penalty). You could solve it using a stream like this:

Stream.of(new Conditional(COND_1, COND_A, () -> {/* do something */}),
          new Conditional(COND_1, COND_B, () -> {/* do something */}),
          new Conditional(COND_2, COND_A, () -> {/* do something */}),
          new Conditional(COND_2, COND_B, () -> {/* do something */}))
      .filter(x -> x.test(var1, varA))
      .findAny()
      .ifPresent(Conditional::run);

That would require a supporting class:

class Conditional implements BiPredicate<Enum1, EnumA>, Runnable
{
    private final Enum1 var1;
    private final EnumA varA;
    private final Runnable runnable;

    public Conditional(Enum1 var1, EnumA varA, Runnable runnable) {
        this.var1 = var1;
        this.varA = varA;
        this.runnable = runnable;
    }

    @Override
    public boolean test(Enum1 enum1, EnumA enumA) {
        return var1 == enum1 && varA == enumA;
    }

    @Override
    public void run() {
        runnable.run();
    }
}
like image 90
Per Huss Avatar answered Oct 22 '22 10:10

Per Huss