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

Simple calculator implemented with lambdas

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

Problem

I was searching for a way to exercise the Java 8 concepts I've been learning, especially pertaining to Lambdas. Incidentally, I hadn't used any swing in a while and wanted a refresher. This is the result of these two pursuits.

```
import java.awt.GridLayout;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.UIManager;
import javax.swing.SwingUtilities;
import javax.swing.WindowConstants;

public class EquationCalculator {
static interface Equation {
double compute(double val1, double val2);
}

public static void main(String[] args) {
try {
for (UIManager.LookAndFeelInfo info : UIManager.getInstalledLookAndFeels()) {
if ("Nimbus".equals(info.getName())) {
UIManager.setLookAndFeel(info.getClassName());
break;
}
}
} catch (Exception e) {
e.printStackTrace();
}

SwingUtilities.invokeLater(() -> new EquationCalculator());
}

public EquationCalculator() {
JFrame frame = new JFrame("Basic Operations");
JPanel panel = new JPanel(new GridLayout(1, 3));
JTextField first = new JTextField("2");
JTextField second = new JTextField("3");
JComboBox calculate = new JComboBox<>();

calculate.addItem("Sum");
calculate.addItem("Difference");
calculate.addItem("Product");
calculate.addItem("Quotient");
calculate.addItem("Exponent");
calculate.addActionListener(
e -> JOptionPane.showMessageDialog(
null, "The result is " +
calculate(
String.valueOf(calculate.getSelectedItem()),
Double.parseDouble(first.getText()),
Double.parseDouble(second.getText())
),
"Result", JOptionPane.INFORMATION_

Solution

Don't use String labels of GUI elements in flow control

It's not good to use the String labels of GUI elements to make decisions.
It would be slightly better if you made "Sum", "Difference", ... global constants, but only slightly.

An enum would be better for this purpose:

enum Operation {
    Sum("Sum", (x, y) -> x + y),
    Difference("Difference", (x, y) -> x - y),
    Product("Product", (x, y) -> x * y),
    Quotient("Quotient", (x, y) -> x / y),
    Exponent("Exponent", Math::pow)
    ;

    private final String label;
    private final Equation equation;

    private Operation(String label, Equation equation) {
        this.label = label;
        this.equation = equation;
    }

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


With this, you could create the JComboBox with Operation items instead of String:

JComboBox calculate = new JComboBox<>();

    calculate.addItem(Operation.Sum);
    calculate.addItem(Operation.Difference);
    calculate.addItem(Operation.Product);
    calculate.addItem(Operation.Quotient);
    calculate.addItem(Operation.Exponent);


Change the call to calculate to this:

calculate(
            ((Operation) calculate.getSelectedItem()).equation,
            Double.parseDouble(first.getText()),
            Double.parseDouble(second.getText())
    ),


And simplify calculate itself to this:

public static double calculate(Equation operation, double val1, double val2) {
    return operation.compute(val1, val2);
}


Avoid pointless evaluations

In calculate, you declare all the equation types at the top but only use one of them.
This is pointless and wasteful.

Simplify lambdas with method references

These lambdas can be replaced with method references:

SwingUtilities.invokeLater(() -> new EquationCalculator());
    // ...
    Equation exponentiate = (alpha, beta) -> Math.pow(alpha, beta);


Like this:

SwingUtilities.invokeLater(EquationCalculator::new);
    // ...
    Equation exponentiate = Math::pow;


Pointless to print stack trace in main

If an exception is thrown in main,
a stack trace will be printed on the console.
There's no need to catch an exception and do the same manually.

Also beware,
it's not a good practice to catch Exception.
It's recommended to catch specific exceptions,
both to signal to readers the things that can possibly go wrong,
and also to avoid truly unexpected exceptions getting caught by the blanket catch.

Code Snippets

enum Operation {
    Sum("Sum", (x, y) -> x + y),
    Difference("Difference", (x, y) -> x - y),
    Product("Product", (x, y) -> x * y),
    Quotient("Quotient", (x, y) -> x / y),
    Exponent("Exponent", Math::pow)
    ;

    private final String label;
    private final Equation equation;

    private Operation(String label, Equation equation) {
        this.label = label;
        this.equation = equation;
    }

    @Override
    public String toString() {
        return label;
    }
}
JComboBox<Operation> calculate = new JComboBox<>();

    calculate.addItem(Operation.Sum);
    calculate.addItem(Operation.Difference);
    calculate.addItem(Operation.Product);
    calculate.addItem(Operation.Quotient);
    calculate.addItem(Operation.Exponent);
calculate(
            ((Operation) calculate.getSelectedItem()).equation,
            Double.parseDouble(first.getText()),
            Double.parseDouble(second.getText())
    ),
public static double calculate(Equation operation, double val1, double val2) {
    return operation.compute(val1, val2);
}
SwingUtilities.invokeLater(() -> new EquationCalculator());
    // ...
    Equation exponentiate = (alpha, beta) -> Math.pow(alpha, beta);

Context

StackExchange Code Review Q#82853, answer score: 8

Revisions (0)

No revisions yet.