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

Length Converter

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

Problem

I have a Swing application that converts lengths. Inches to centimeter, feet to yard, etc. I’m wondering if I could make the super large HashMap a little smaller, or more efficient. Any other suggestions are also appreciated.

```
import java.awt.*;
import java.awt.event.*;
import java.util.HashMap;
import javax.swing.*;
public class LengthConverter{
private JFrame frame;
private JLabel welcomeLabel;
private JPanel fromPanel;
private JLabel centerLabel;
private JTextField fromField;
private JComboBox fromBox;
private JPanel toPanel;
private JTextField toField;
private JComboBox toBox;
private JButton submitButton;
private JLabel noteLabel;
private JPanel bottomPanel;
private final String[] lengthTypes = {"Inches", "Centimeters", "Feet", "Yards", "Meters", "Millimeters"};
private final HashMap> conversions = new HashMap<>();
public LengthConverter() {
conversions.put("Inches", new HashMap<>());

conversions.get("Inches").put("Inches", 1.0);
conversions.get("Inches").put("Centimeters", 2.54);
conversions.get("Inches").put("Feet", 0.0833333);
conversions.get("Inches").put("Yards", 0.0277778);
conversions.get("Inches").put("Meters", 0.0254);
conversions.get("Inches").put("Millimeters", 25.4);

conversions.put("Centimeters", new HashMap<>());

conversions.get("Centimeters").put("Inches", 0.393701);
conversions.get("Centimeters").put("Centimeters", 1.0);
conversions.get("Centimeters").put("Feet", 0.0328084);
conversions.get("Centimeters").put("Yards", 0.0109361);
conversions.get("Centimeters").put("Meters", 0.01);
conversions.get("Centimeters").put("Millimeters", 10.0);

conversions.put("Feet", new HashMap<>());

conversions.get("Feet").put("Inches", 12.0);
conversions.get("Feet").put("Centimeters", 30.48);
conversions.get("Feet").put("Feet", 1.0);
conversions.get

Solution

Instead of a nested hash map containing the conversion factor from
every unit to every other unit, it is sufficient to have a mapping
from each unit to a single common unit, e.g. meter:

HashMap conversions = new HashMap<>();

conversions.put("Centimeters", 0.01);
conversions.put("Inches", 0.0254);
// ...


Then the conversion factor between two units can simply be calculated as

Double conversionRate = conversions.get(fromUnit) / conversions.get(toUnit);


Actually you don't need a hash map at all, you could store the
information in two parallel arrays:

private final String[] lengthTypes = { "Inches", "Centimeters", "Feet", "Yards", "Meters", "Millimeters"};
private final double[] conversionFactors = { 0.054, 0.01, 0.3048, 0.9144, 1.0, 0.001 };


Then

double conversionRate = conversionFactors[fromBox.getSelectedIndex()] / conversionFactors[toBox.getSelectedIndex()];


Alternatively, define a

class Unit {
    String name;
    double conversionFactor;

    Unit(String name, double conversionFactor) {
        this.name = name;
        this.conversionFactor = conversionFactor;
    }
}


and the list of available units with

Unit[] units = {
    new Unit("Centimeters", 0.01),
    new Unit("Inches", 0.0254)
    // ...
};


Then the unit name and corresponding factor is defined together, and it is less
error-prone if units are reordered or renamed. The combo boxes
would then be populated with

for (Unit unit : units) {
    fromBox.addItem(unit.name);
    toBox.addItem(unit.name);
}


and the conversion factor between two units is

double conversionRate = units[fromBox.getSelectedIndex()].conversionFactor / units[toBox.getSelectedIndex()].conversionFactor;

Code Snippets

HashMap<String, Double> conversions = new HashMap<>();

conversions.put("Centimeters", 0.01);
conversions.put("Inches", 0.0254);
// ...
Double conversionRate = conversions.get(fromUnit) / conversions.get(toUnit);
private final String[] lengthTypes = { "Inches", "Centimeters", "Feet", "Yards", "Meters", "Millimeters"};
private final double[] conversionFactors = { 0.054, 0.01, 0.3048, 0.9144, 1.0, 0.001 };
double conversionRate = conversionFactors[fromBox.getSelectedIndex()] / conversionFactors[toBox.getSelectedIndex()];
class Unit {
    String name;
    double conversionFactor;

    Unit(String name, double conversionFactor) {
        this.name = name;
        this.conversionFactor = conversionFactor;
    }
}

Context

StackExchange Code Review Q#87594, answer score: 6

Revisions (0)

No revisions yet.