Home > front end >  Multiple if Statements using reference number
Multiple if Statements using reference number

Time:12-16

The code below compiles and does its job, however lets say I needed to added another 100 if statements that uses a reference. Whats the most efficient way to write multiple if statements?

public String getForceDetails(String ref) {
    if (ref.equals("IW1")) {
        setupForces();
        return (ForceDetails.get(0).toString());
    } else if (ref.equals("SS2")) {
        setupForces();
        return (ForceDetails.get(1).toString());
    } else if (ref.equals("WB3")) {
        setupForces();
        return (ForceDetails.get(2).toString());
    } else if (ref.equals("IW4")) {
        setupForces();
        return (ForceDetails.get(3).toString());
    } else if (ref.equals("WB5")) {
        setupForces();
        return (ForceDetails.get(4).toString());
    } else if (ref.equals("SS6")) {
        setupForces();
        return (ForceDetails.get(5).toString());
    } else if (ref.equals("SS7")) {
        setupForces();
        return (ForceDetails.get(6).toString());
    } else if (ref.equals("WB9")) {
        setupForces();
        return (ForceDetails.get(7).toString());
    } else if (ref.equals("IW10")) {
        setupForces();
        return (ForceDetails.get(8).toString());
    } else {
        return "\nNo such force";
    }
}
private void setupForces()
{
    ForceDetails.add(new starShip("IW1","Twisters",200,200,ForceState.DOCKED,10,0,0,false));
    ForceDetails.add(new starShip("SS2","Enterprise",300,200,ForceState.DOCKED,0,10,20,false));
    ForceDetails.add(new starShip("WB3","Droop",300,100,ForceState.DOCKED,0,0,0,false));
    ForceDetails.add(new starShip("IW4","Wingers",200,400,ForceState.DOCKED,20,0,0,false));
    ForceDetails.add(new starShip("WB5","Hang",400,300,ForceState.DOCKED,0,0,0,true));
    ForceDetails.add(new starShip("SS6","Voyager",450,200,ForceState.DOCKED,0,15,10,false));
    ForceDetails.add(new starShip("SS7","Explorer",120, 65,ForceState.DOCKED,0,4,5,false));
    ForceDetails.add(new starShip("WB9","Hover",300,400,ForceState.DOCKED,0,0,0,false));
    ForceDetails.add(new starShip("IW10","Flyers",200,100,ForceState.DOCKED,5,0,0,false));
}

CodePudding user response:

The obvious choice would be a switch statement over ref:

switch (ref) {
    case "IW1":
        setupForces();
        return (ForceDetails.get(0).toString());
        break;
    case "SS2":
        setupForces();
        return (ForceDetails.get(1).toString());
        break;
    // etc.
}

If the code to execute always looks the like this (calling setupForces() and getting the n-th element of ForceDetails) you could also use a map that lets you retrieve n (Map<String, Integer>) which you populate with key-value-pairs like "IW1"->0 and "SS2"->1 etc. The map solution also has the charme that you do not need to repeat the code that is basically equal for all cases which would be rather inconvenient if you have to change this later.

CodePudding user response:

Well there is no inbuilt solution to that. What you can do is create a Map of condition -> result and return the value to the key.

Map<String, String> mapCondToRes = new HashMap<>();

public String getForceDetails(String ref) {
    setupForces();
    return mapCondToRes.get(ref);
}

You can check for validations and put more conditions very easily and elegantly.

CodePudding user response:

In the existing code, each invocation of getForceDetails with a valid ref causes adding of 9 entries to a collection of starships ForceDetails. It is doubtful that this behaviour is intended, possibly a lazy initialization of ForceDetails was implied.

Next, to get rid of the multiple if statements using of the map is definitely more preferable than converting into switch statement and copying the same multiple calls to setupForces(). It could make sense to create a map Map<String, starship> instead of the list and populate it in setupForces (so there's no need to have a separate map of references to the index in the list):

Map<String, starShip> forces = new HashMap<>();

private void setupForces() {
    forces.put("IW1", new starShip("IW1","Twisters",200,200,ForceState.DOCKED,10,0,0,false));
    forces.put("SS2", new starShip("SS2","Enterprise",300,200,ForceState.DOCKED,0,10,20,false));
// ... add other starships mapped by their ids
}

public String getForceDetails(String ref) {
    if (forces.isEmpty()) {
        setupForces();
    }
    return Optional.ofNullable(forces.get(ref))
        .map(starShip::toString)
        .orElse("No such force found");
}

CodePudding user response:

Use a java stream, you should read about them, you'll find it useful later as you progress on Java.

For the following code, I assume you have a getter for your "key" values inside your starShip class ("IW1", "SS2", "WB3"...).

This code also assumes that you cannot change your current List approach, If you can, a Map would be a even better.

private static final String NO_FORCE = "\nNo such force";
public String getForceDetails(String ref) {
    String result = ForceDetails.stream() // <-- It's even faster if you use `parallelStream` however is known to have non-thread-safe issues
        .filter(starShipItem -> Objects.equals(starShipItem.getKey(), ref))
        .map(String::valueOf).findFirst()
        .orElse(NO_FORCE)
    ;
    if (NO_FORCE.equals(result)) {
        return NO_FORCE;
    }
    setupForces();
    return result;
}

Also, I recommend you to take a look at hackerrank challenges, you'll learn a lot more there.

  • Related