HiveBrain v1.2.0
Get Started
← Back to all entries
patternjavaMinor

Yet Another Java CLI Calculator

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
javayetclianothercalculator

Problem

In the spirit of April 2015 Community Challenge, I have created two Java-based calculators with the following codebase layout:

  • An interface Calculeightor for describing how values can be appended into a stream and then reduced to a single result given an operator.



  • An enum Operator to represent the operators.



  • The GUI implementation CalculeightorGUI.



  • The CLI implementation CalculeightorCLI.



  • A unit test for the CLI implementation CalculeightorCommandLineInterfaceTest.



The name uses eight as a pun, since this is written with Java 8 features in mind. Also, the unit test spells out CLI in full because appending Test to that creates another word that some may find inappropriate...

Without further ado, what follows are the code for Operator, CalculeightorCLI and CalculeightorCommandLineInterfaceTest. For the review of the other code, please look at the other review.

General feedback I am looking for:

  • Any places where I can simplify the logic?



  • Are Javadocs clear and concise enough?



  • Any major faults?



Operator

```
public enum Operator implements BinaryOperator {
ADD {
@Override
public Double apply(Double t, Double u) {
return Double.valueOf(t.doubleValue() + u.doubleValue());
}

@Override
public String toString() {
return "+";
}
},
SUBTRACT {
@Override
public Double apply(Double t, Double u) {
return Double.valueOf(t.doubleValue() - u.doubleValue());
}

@Override
public String toString() {
return "-";
}
},
MULTIPLY {
@Override
public Double apply(Double t, Double u) {
return Double.valueOf(t.doubleValue() * u.doubleValue());
}

@Override
public String toString() {
return "*";
}
},
DIVIDE {
@Override
public Double apply(Double t, Double u) {
return Double.val

Solution

enum improvements

I would use a constructor for your enum to make things more consise.

I would also use the DoubleBinaryOperator instead, which works directly with the primitive double type.

Additionally, you might as well make your Operator of(String operator) method public and your SYMBOLS map private.

Applying these changes will make your enum look like this:

public enum Operator implements DoubleBinaryOperator {
    ADD("+", (a, b) -> a + b),
    SUBTRACT("-", (a, b) -> a - b),
    MULTIPLY("*", (a, b) -> a * b),
    DIVIDE("+", (a, b) -> a / b),
    MODULUS("%", (a, b) -> a % b),
    EXPONENT("^", (a, b) -> Math.pow(a, b));

    private final String name;
    private final DoubleBinaryOperator op;

    private Operator(String name, DoubleBinaryOperator op) {
        this.name = name;
        this.op = op;
    }

    @Override
    public double applyAsDouble(double left, double right) {
        return op.applyAsDouble(left, right);
    }

    private static final Map SYMBOLS = Stream.of(values()).collect(
        Collectors.toMap(Object::toString, Function.identity()));

    public static Operator of(String operator) {
        return SYMBOLS.get(operator);
    }

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

Code Snippets

public enum Operator implements DoubleBinaryOperator {
    ADD("+", (a, b) -> a + b),
    SUBTRACT("-", (a, b) -> a - b),
    MULTIPLY("*", (a, b) -> a * b),
    DIVIDE("+", (a, b) -> a / b),
    MODULUS("%", (a, b) -> a % b),
    EXPONENT("^", (a, b) -> Math.pow(a, b));

    private final String name;
    private final DoubleBinaryOperator op;

    private Operator(String name, DoubleBinaryOperator op) {
        this.name = name;
        this.op = op;
    }

    @Override
    public double applyAsDouble(double left, double right) {
        return op.applyAsDouble(left, right);
    }

    private static final Map<String, Operator> SYMBOLS = Stream.of(values()).collect(
        Collectors.toMap(Object::toString, Function.identity()));


    public static Operator of(String operator) {
        return SYMBOLS.get(operator);
    }

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

Context

StackExchange Code Review Q#88007, answer score: 5

Revisions (0)

No revisions yet.