how can I make this calculator using only one method?

Viewed 133

I'm trying to make this calculator I can make it using 4 methods, one for addition one for subtraction and ..... but I want to make it a simple as possible. how can I perform the 4 main actions using one method and then call it in static main?

package com.company;

import java.util.Scanner;

public class Main {
    final static String first = "first number: ";
    final static String sec = "second number: ";

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        System.out.println("what do you want to use? (multiply (input *), divide (input /), subtract (input -), addition (input +)");
        String input = scanner.nextLine();
        double answer = calculation(input);                 ----------------------
        System.out.println(answer);
    }
    public static double calculation(double element){       ----------------------
        Scanner scanner = new Scanner(System.in);
        System.out.println(first);
        double firstInput = scanner.nextDouble();
        System.out.println(sec);
        double secInput = scanner.nextDouble();
        return firstInput element secInput;                 ----------------------
    }
}

can I change the element to (+ - * /) ? (the ------------------ part is were I have a problem)

2 Answers

You might wanna take a look at OOP principles, using inheritance and polymorphism, you should be able to have a single method defined in a interface and multiple implementations of it in your classes, so you can have a Calculation interface with a execute method an then you implement that interface with a class like Sum where the execute method does the real sum.

public interface Calculation {
    Double execute(Double a, Double b);
}

public class Sum implements Calculation {
    @Override
    public Double execute(Double a, Double b) {
        return a+b;
    }
}

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        System.out.println("what do you want to use? (multiply => *, divide => /, subtract => -, addition => +");
        String input = scanner.nextLine();
        Calculation calculation;
        if (input.equals("+")) calculation = new Sum();
        else calculation = new Sum();// Just initializing calculation to avoid compilation error
        double answer = execute(calculation);
    }

    private static double execute(Calculation calculation){
        Scanner scanner = new Scanner(System.in);
        double firstInput = scanner.nextDouble();
        System.out.println(firstInput);
        double secInput = scanner.nextDouble();
        System.out.println(secInput);
        return calculation.execute(firstInput, secInput);
    }
}

You could perform it using enum and lambda functions. This approach allows you to add operations to your code easily, without need of rewriting your calculation method. First of all use Scanner with try-with-resources or call scanner.close() after Scanner is no longer needed. Then probably better not to create two Scanner object , instead just unite your input parts in one method (If you still want to use two Scanner instances remember to wrap System.in in decorator to prevent it from closing). Also you could probably add some validation to prevent input errors(and let user try to input data again). The main idea is to create enum which contains a BiFunction for every operation, that you apply to your pair of numbers. It could look like this:

public class Main {

    private final static String first = "first number: ";
    private final static String sec = "second number: ";

    public static void main(String[] args) {
        try (Scanner scanner = new Scanner(System.in)) {
            String operationTypes = Arrays.stream(OperationType.values())
                    .map(type -> String.format("%s (input %s)", type.toString(), type.sign))
                    .collect(Collectors.joining("(", ", ", ")"));
            System.out.println("what do you want to use? " + operationTypes);
            String input = scanner.nextLine();
            System.out.println(first);
            double firstInput = scanner.nextDouble();
            System.out.println(sec);
            double secInput = scanner.nextDouble();
            OperationType operationType = OperationType.fromSign(input).orElseThrow();
            double answer = calculation(operationType, firstInput, secInput);
            System.out.println(answer);
        }
    }

    public static double calculation(OperationType operationType, double firstInput, double secInput) {
        return operationType.operation.apply(firstInput, secInput);
    }

    enum OperationType {

        ADD("+", Double::sum),
        SUBTRACT("-", (a, b) -> a - b),
        MULTIPLY("*", (a, b) -> a * b),
        DIVIDE("/", (a, b) -> a / b);

        String sign;
        BiFunction<Double, Double, Double> operation;

        OperationType(String sign, BiFunction<Double, Double, Double> operation) {
            this.sign = sign;
            this.operation = operation;
        }

        public static Optional<OperationType> fromSign(String sign) {
            return Arrays.stream(OperationType.values())
                    .filter(operationType -> operationType.sign.equals(sign))
                    .findAny();
        }

        @Override
        public String toString() {
            return this.name().toLowerCase();
        }
    }

}
Related