station
station

Reputation: 7145

How can I optimize the following if else?

I have the following if else block.

if (result.first && result.last) {
    output= "both present"
} else if (!result.first && result.last) {
    output= "last present"
} else if (result.first && !result.last) {
    output= "first present"
} else {
    output = "none present"
}

The code looks clumsy. Is there any way I can optimize it.

Upvotes: 1

Views: 111

Answers (5)

Kamil W
Kamil W

Reputation: 2376

This is my approach to deal with statements like that, lets assume that result is an object and has two primitive boolean members (bear in mind, that in "big" boolean might be a null) first and last (with getter methods)

public class Result {

  private boolean first;
  private boolean last;

//getters, constructor etc

}

Let's wrap conditions in Predicate and put it into map where key is predicate and value is an expected value:

private final static Predicate<Result> = RESULT_1-> result.getFirst() && result.getLast();
private final static Predicate<Result> = RESULT_2 -> !result.getFirst() && result.getLast();
private final static Predicate<Result> = RESULT_3 -> result.getFirst() && !result.getLast();

private final static DEFAULT_VALUE = "none present";

private final static Map<Predicate<Result>, String> RESULT_MAP = Map.of(
RESULT_1, "both present",
RESULT_2, "last present",
RESULT_3, "first presnt");

Then you can use it in this way:

String output = map.entrySet().stream().filter(predicate -> predicate.getKey().test(resultToTest))
        .findFirst()
        .map(Entry::getValue).orElse(DEFAULT_VALUE);

Ofcourse give those variables meanigfull names, do some extraction etc. In this approach when you have to add new condition to code, you just add new predicate to map, and that's all. In case small as yours, you don't have to write flexiable code as I showed, but in more complicated issues this approach is sutiable.

Upvotes: 0

Alex Shesterov
Alex Shesterov

Reputation: 27585

Just a fancy way is to use a ternary operator. This is no different than using an if-cascade though, but is a single assignment (handy if output is final, though not strictly necessary even in this case).

output = 
  result.first 
    ? (result.last ? "both present" : "first present")
    : (result.last ? "last present" : "none present");

Since there are 4 possible outcomes, it's impossible to reduce it below log_2(4) == 2 nested conditions.

You could also use a predefined lookup map.

Upvotes: 2

Andreas
Andreas

Reputation: 159215

Instead of checking both in single condition, use nested if statements:

if (result.first) {
    if (result.last) {
        output = "both present";
    } else {
        output = "first present";
    }
} else {
    if (result.last) {
        output = "last present";
    } else {
        output = "none present";
    }
}

That easily leads to using ternary conditional operator:

if (result.first) {
    output = (result.last ? "both present" : "first present");
} else {
    output = (result.last ? "last present" : "none present");
}

Which can also be nested:

output = (result.first ? (result.last ? "both present" : "first present")
                       : (result.last ? "last present" : "none present"));

If there were many booleans to check, deeply nesting can become cumbersome, so you could alternatively use bit-masking:

private static final String[] OUTPUTS = { "none present", "first present",
                                          "last present", "both present" };
output = OUTPUTS[(result.first ? 1 : 0) + (result.last ? 2 : 0)];

Upvotes: 1

Ali
Ali

Reputation: 436

output = "none present"
if (result.first){
   output= "first present"
   if(result.last){
      output= "both present"
    }
} else if (result.last) {
output= "last present"
}

Upvotes: 0

Robert Br&#228;utigam
Robert Br&#228;utigam

Reputation: 7744

if (result.first && result.last){
   output= "both present"
} else if (result.last) {
   output= "last present"
} else if (result.first) {
   output= "first present"
} else {
   output = "none present"
}

Also, if you can, you might put the logic into the "result", then you don't have to "get" things that belong to the result. You might even replace the if/else with polymorphism if you push the logic up far enough.

Upvotes: 1

Related Questions