GamZ
GamZ

Reputation: 1

How can I avoid repeated if-statement?

I write a java application to handle log file had millions of line In program there is such a pseudo code

if(optionA is On)
  call object A's method

if(optionB is On)
  call object B's method

if(optionC is On)
  call object C's method
...

The options in IFs are config value get from a config file This pseudo code called in each log line, so it called millions of time

Because of speed and simplicity, I want to remove this multi IFs. To see such a many IFs are unpleasant to me. Is theare a good way to get around this annoying IFs?

Upvotes: 0

Views: 1947

Answers (4)

euphoria83
euphoria83

Reputation: 15136

If the method is the same for all objects, then create a option-to-object hash table and call the method based on the option.

HashMap<Option,ActionObject> map ;
for (Option option: map.keySet()) {
    if (optionIsTrue(option)) {  
        map.get(option).performAction() ;
    }
}

Upvotes: 0

MarcoS
MarcoS

Reputation: 13564

It really depends what you want to optimize (see templatetypedef's comment). If you just want to reduce code footprint you may do something like this

// let's assume you have an Option interface with isTrue() method
// let's assume you have an Action interface with performAction() method

Map<Option,Action> actions = new HashMap<Option,Action>();
// initialize actions with instance of your objects so that you have:
// optionA -> actionA
// optionB -> actionB
// etc.
// this is done only once

Option[] currentOptions;
// read the current option values and put them in an array
for (int i = 0; i < currentOptions.lengt; i++) {
    if (currentOptions[i].isTrue())
        actions.get(currentOptions[i]).performAction();
}

Upvotes: 0

Laurent Pireyn
Laurent Pireyn

Reputation: 6875

Long sequences of if statements are not always a bad thing. If you want to do it the right way though, you have to define the mapping of your options to their "handlers" in a data structure instead of hardcode it in if statements.

You can define a one-method interface and have A, B and C (in your example) implement it:

public interface OptionHandler { // For lack of a better name...
    void handleOption(); // You could pass parameters here
}

You can then define a map of the options to their handlers:

private final Map<Option, OptionHandler> optionHandlers = new HashMap<Option, OptionHandler>();

You would then replace your sequence of if statements with something like:

for (Option option : options) {
    if (!option.isOn()) {
        // Skip off option
        continue;
    }
    OptionHandler handler = optionHandlers.get(option);
    if (handler != null) {
        handler.handleOption();
    }
}

Upvotes: 0

Nodebody
Nodebody

Reputation: 1433

If the objects share a common interface, you could create a method like this:

private void callOptional(myInterface obj, boolean flag) {
  if (option) obj.method();
}

That way you have eliminated the IFs. But you still have a long list of common code. To make it more DRY, I'd add the object reference to the list where you store the options and then just do a for loop:

for (OptionObjectPair ooPair : optionObjectList) {
  callOptional(ooPair.obj, ooPair.flag)
}

You can then even change the interface of the callOptional method to take an OptionObjectPair directly.

Upvotes: 1

Related Questions