What is the best way to set class variable which is an enum based on some conditional logic on a dependent enum in java?

RamPrasadBismil :

I am trying to map values from one enum to the other based on some calculation or conditional logic that I need to perform to set the correct enum value for the class variable. How can I do this without using too many if/else, switch statements?

Enum BRAND {
 MINI, FERRARI, PAGANI
}

and another enum

Enum ENGINE {
LEVEL1, LEVEL2, LEVEL3
}

And I have a class like :

Class Car() {

 int model;
 int year;
 Engine engine;

 // I want to calculate set the engine depending on the brand based on conditional logic
 public carEngineCalculator (Brand b) {
   Car mycar = new Car();

   if (mycar.isSuperCar(b) {
    if (mycar.isCrazyGood(b)) {
        mycar.engine = ENGINE.LEVEL1;
    } else {
        mycar.engine = ENGINE.LEVEL2;
    }
   } else {
    mycar.engine = ENGINE.LEVEL3;
   }
   ... //And the conditions can be more complex
 }

 public boolean isSuperCar(Brand b) {
    if (b.FERRARI || b.PAGANI) {
     return true;
    } 
    return false;
 }

 public boolean isCrazyGood(Brand b) {
    return ...;
 }
} 

There can be more than one such conditions that need to be checked in order to set the values and I want to avoid nasty if/else/switch statements as shown above. Is there a more functional way of doing this.

Ralf Renz :

Using predicates as I said would look like this:

public enum Brand {
    MINI,
    FERRARI,
    PAGANI
}

public enum Engine {
    LEVEL1,
    LEVEL2,
    LEVEL3
}

public class Entry {
    public final Predicate<Car> pred;
    public final Engine engine;

    public Entry(Predicate<Car> pred, Engine engine) {
        this.pred = pred;
        this.engine = engine;
    }
}

public class Car {
    int model;
    int year;
    Engine engine;

    public void carEngineCalculator(Brand b) {
        Car mycar = new Car();

        List<Entry> cases = new ArrayList<>();
        cases.add(new Entry(c -> c.isSuperCar(b) && c.isCrazyGood(b), Engine.LEVEL1));
        cases.add(new Entry(c -> c.isSuperCar(b) && !c.isCrazyGood(b), Engine.LEVEL2));
        cases.add(new Entry(c -> !c.isSuperCar(b), Engine.LEVEL3));

        mycar.engine = cases.stream().filter(x -> x.pred.test(mycar)).findFirst().get().engine;

    }

    public boolean isSuperCar(Brand b) {
        if ((b == Brand.FERRARI) || (b == Brand.PAGANI)) {
            return true;
        }
        return false;
    }

    public boolean isCrazyGood(Brand b) {
        return false;
    }
}

You create a List with Predicates and Results and use stream, filter and findFirst to go through the list and find the right result. If the conditions are simpler than you don't need predicates and test it a little bit different.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=74039&siteId=1