Alaskaboi
Alaskaboi

Reputation: 37

Modifying duplicate if-else statements into a cleaner code

Im making a calculator Gui. Is there any way to make this code look cleaner without duplicating lines.

double num1, num2, ans, doub;
num1 = Double.parseDouble(FirstInput.getText());
num2 = Double.parseDouble(SecondInput.getText());
oper = (Operator.getText());

if(oper.equals("+")){
    ans = num1 + num2;
    doub = Math.round(ans * 100000.0) / 100000.0;
    if(doub == (int) ans){
        Answer.setText(Integer.toString((int) ans));
    } else{
        Answer.setText(Double.toString(doub));
    }
}
if(oper.equals("-")){
    ans = num1 - num2;
    doub = Math.round(ans * 100000.0) / 100000.0;
    if(doub == (int) ans){
        Answer.setText(Integer.toString((int) ans));
    } else{
        Answer.setText(Double.toString(doub));
    }
}
if(oper.equals("/")){
    ans = num1 / num2;
    doub = Math.round(ans * 100000.0) / 100000.0;
    if(doub == (int) ans){
        Answer.setText(Integer.toString((int) ans));
    } else{
        Answer.setText(Double.toString(doub));
    }
}
if(oper.equals("x")){
    ans = num1 * num2;
    doub = Math.round(ans * 100000.0) / 100000.0;
    if(doub == (int) ans){
        Answer.setText(Integer.toString((int) ans));
    } else{
        Answer.setText(Double.toString(doub));
    }
}

Upvotes: 2

Views: 145

Answers (4)

Debapriya Biswas
Debapriya Biswas

Reputation: 1349

I liked Lino's answer to use DoubleBinaryOperator .(+1) for that. Most ifs or switch can be replaced by polymorphism . Functions without ifs/switch are easier to read/test and maintain . Greatly influenced from this google talk https://www.youtube.com/watch?v=4F72VULWFvc You can use this ENUM version as well . You need JDK 8 for this

public enum Operation {

    PLUS("+", (x, y) -> x + y),

    MINUS("-", (x, y) -> x - y),

    MULTIPLY("*", (x, y) -> x * y),

    DIVIDE("/", (x, y) -> x / y);

    private final DoubleBinaryOperator op;
    private final String symbol;

    public double apply(double x, double y) {
        return op.applyAsDouble(x, y);
    }

    Operation(String symbol, DoubleBinaryOperator op) {
        this.symbol = symbol;
        this.op = op;
    }

    public String toString() {
        return symbol;
    }

    public static void setAnswerText(double num1, double num2, Operation operator) {
        final double ans = operator.apply(num1, num2);
        final double doub = Math.round(ans * 100000.0) / 100000.0;
        if (doub == (int) ans) {

            Answer.setText(Integer.toString((int) ans));
        } else {

            Answer.setText(Double.toString(doub));
        }
    }

    public static void main(String[] args) {
        final double num1 = 100;
        final double num2 = 200;
        final Operation oper = Operation.PLUS;
        setAnswerText(num1, num2, oper);

    }
}

Upvotes: 0

Lino
Lino

Reputation: 19910

With java-8 you could make it quite fancy by introducing a new method which accepts the numbers and an DoubleBinaryOperator:

public void setAnswerText(double num1, double num2, DoubleBinaryOperator operator){
    final double ans = operator.applyAsDouble(num1, num2);
    final double doub = Math.round(ans * 100000.0) / 100000.0;
    if(doub == (int) ans){
        Answer.setText(Integer.toString((int) ans));
    } else{
        Answer.setText(Double.toString(doub));
    }
}

and using a switch statement:

final double num1 = Double.parseDouble(FirstInput.getText());
final double num2 = Double.parseDouble(SecondInput.getText());
final String oper = (Operator.getText());
final DoubleBinaryOperator operator;
switch(oper){
    case "+": 
        operator = (a, b) -> a+b;
        break;
    case "-": 
        operator = (a, b) -> a-b;
        break;
    case "/": 
        operator = (a, b) -> a/b;
        break;
    case "x": 
        operator = (a, b) -> a*b;
        break;
    default:
        throw new UnsupportedOperationException();
}

setAnswerText(num1, num2, operator);

That way, you're finding the matching operator in the switch-statment and then executing the method with the numbers and the found operator

Upvotes: 5

Iris Hunkeler
Iris Hunkeler

Reputation: 208

You could extract the part where you prepare the answer into a separate method, so you do not need to write that code multiple times, e.g.

private static void prepAnswer(double ans){
    double doub = Math.round(ans * 100000.0) / 100000.0;
    if(doub == (int) ans){
        Answer.setText(Integer.toString((int) ans));
    } else{
        Answer.setText(Double.toString(doub));
    }
}

Additionally, you could use a switch-case statement. That would look like this:

    String oper = (Operator.getText());
    switch(oper) {
        case "+": prepAnswer(num1 + num2); break;
        case "-": prepAnswer(num1 - num2); break;
        case "/": prepAnswer(num1 / num2); break;
        case "x": prepAnswer(num1 * num2); break;    
        default: throw new UnsupportedOperationException();
    }

Upvotes: 0

sandeshch
sandeshch

Reputation: 11

Just consolidating

    double num1, num2, ans, doub;
    num1 = Double.parseDouble(FirstInput.getText());
    num2 = Double.parseDouble(SecondInput.getText());
    oper = (Operator.getText());

    switch(oper){
    case "+" :  ans = num1 + num2; break;
    case "-" :  ans = num1 - num2; break;
    case "/" :  ans = num1 / num2; break;
    case "*" :  ans = num1 * num2; break;
    }
    setAnswer(ans);
}

    /**
     * @param ans
     */
    private static void setAnswer(double ans) {
        double doub;
        doub = Math.round(ans * 100000.0) / 100000.0;
        if (doub == (int) ans) {
            Answer.setText(Integer.toString((int) ans));
        } else {
            Answer.setText(Double.toString(doub));
        }
    }

Upvotes: 0

Related Questions