patternjavaMinor
Length Converter
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
```
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:
Then the conversion factor between two units can simply be calculated as
Actually you don't need a hash map at all, you could store the
information in two parallel arrays:
Then
Alternatively, define a
and the list of available units with
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
and the conversion factor between two units is
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.