首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >长度转换器

长度转换器
EN

Code Review用户
提问于 2015-04-21 20:34:29
回答 2查看 6.9K关注 0票数 5

我有一个转换长度的Swing应用程序。英寸到厘米,脚到院子,等等。我想知道我是否能让超大的HashMap变得更小,或者更高效。任何其他建议也将受到赞赏。

代码语言:javascript
复制
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<String> fromBox;
    private JPanel toPanel;
    private JTextField toField;
    private JComboBox<String> toBox;
    private JButton submitButton;
    private JLabel noteLabel;
    private JPanel bottomPanel;
    private final String[] lengthTypes = {"Inches", "Centimeters", "Feet", "Yards", "Meters", "Millimeters"};
    private final HashMap<String, HashMap<String, Double>> 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("Feet").put("Yards", 0.3333333);
        conversions.get("Feet").put("Meters", 0.3048);
        conversions.get("Feet").put("Millimeters", 304.8);

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

        conversions.get("Yards").put("Inches", 36.0);
        conversions.get("Yards").put("Centimeters", 91.44);
        conversions.get("Yards").put("Feet", 3.0);
        conversions.get("Yards").put("Yards", 1.0);
        conversions.get("Yards").put("Meters", 0.9144);
        conversions.get("Yards").put("Millimeters", 914.4);

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

        conversions.get("Meters").put("Inches", 39.3701);
        conversions.get("Meters").put("Centimeters", 100.0);
        conversions.get("Meters").put("Feet", 3.28084);
        conversions.get("Meters").put("Yards", 1.09361);
        conversions.get("Meters").put("Meters", 1.0);
        conversions.get("Meters").put("Millimeters", 1000.0);

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

        conversions.get("Millimeters").put("Inches", 0.0393701);
        conversions.get("Millimeters").put("Centimeters", 0.1);
        conversions.get("Millimeters").put("Feet", 0.00328084);
        conversions.get("Millimeters").put("Yards", 0.00109361);
        conversions.get("Millimeters").put("Meters", 0.001);
        conversions.get("Millimeters").put("Millimeters", 1.0);
    }
    public static void main(String[] args) {
        new LengthConverter().go();
    }
    public void go() {
        frame = new JFrame("Length Conversions");
        fromPanel = new JPanel();
        centerLabel = new JLabel("Is...");
        fromField = new JTextField(10);
        fromBox = new JComboBox<>(lengthTypes);
        toPanel = new JPanel();
        toBox = new JComboBox<>(lengthTypes);
        toField = new JTextField(10);
        toField.setEnabled(false);
        welcomeLabel = new JLabel("Welcome to the length converter!");
        submitButton = new JButton("Convert!");
        noteLabel = new JLabel("Note: Rounds to fit the text field.");
        bottomPanel = new JPanel();
        submitButton.addActionListener(new SubmitListener());

        fromPanel.setLayout(new BoxLayout(fromPanel, BoxLayout.X_AXIS));
        fromPanel.add(fromField);
        fromPanel.add(fromBox);

        toPanel.setLayout(new BoxLayout(toPanel, BoxLayout.X_AXIS));
        toPanel.add(toField);
        toPanel.add(toBox);

        bottomPanel.setLayout(new BoxLayout(bottomPanel, BoxLayout.X_AXIS));
        bottomPanel.add(noteLabel);
        bottomPanel.add(submitButton);

        Font labelFont = new Font("Arial", Font.BOLD, 24);
        welcomeLabel.setFont(labelFont);

        frame.setLayout(new BorderLayout());
        Container window = frame.getContentPane();

        window.add(BorderLayout.NORTH, welcomeLabel);
        window.add(BorderLayout.WEST, fromPanel);
        window.add(BorderLayout.EAST, toPanel);
        window.add(BorderLayout.CENTER, centerLabel);
        window.add(BorderLayout.SOUTH, bottomPanel);

        frame.pack();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);
    }
    class SubmitListener implements ActionListener {

        @Override
        public void actionPerformed(ActionEvent e) {
            Double numToConvert = Double.parseDouble(fromField.getText());
            Double conversionRate = conversions.get(fromBox.getSelectedItem()).get(toBox.getSelectedItem());
            String result = Double.toString(numToConvert * conversionRate);
            int length = result.length();
            if (length > 4) {
                Dimension d = frame.getSize();
                frame.setSize(length + d.width - 16, d.height);
                toField.setColumns(length);
            }
            else {
                toField.setColumns(4);
                frame.pack();
            }
            toField.setText(result);
            frame.revalidate();
        }

    }
}
EN

回答 2

Code Review用户

回答已采纳

发布于 2015-04-21 20:53:52

与包含从每个单元到每个其他单元的转换因子的嵌套散列映射不同,只需将每个单元映射为单个公共单元即可,例如仪表:

代码语言:javascript
复制
HashMap<String, Double> conversions = new HashMap<>();

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

然后,两个单位之间的转换系数可以简单地计算为

代码语言:javascript
复制
Double conversionRate = conversions.get(fromUnit) / conversions.get(toUnit);

实际上,您根本不需要一个散列映射,您可以将信息存储在两个并行数组中:

代码语言:javascript
复制
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 };

然后

代码语言:javascript
复制
double conversionRate = conversionFactors[fromBox.getSelectedIndex()] / conversionFactors[toBox.getSelectedIndex()];

或者,定义

代码语言:javascript
复制
class Unit {
    String name;
    double conversionFactor;

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

和可用单位的清单

代码语言:javascript
复制
Unit[] units = {
    new Unit("Centimeters", 0.01),
    new Unit("Inches", 0.0254)
    // ...
};

然后将单元名称和相应的因子定义在一起,如果对单元进行重新排序或重命名,则不太容易出错。然后,组合框将被填充

代码语言:javascript
复制
for (Unit unit : units) {
    fromBox.addItem(unit.name);
    toBox.addItem(unit.name);
}

两个单位之间的换算系数是

代码语言:javascript
复制
double conversionRate = units[fromBox.getSelectedIndex()].conversionFactor / units[toBox.getSelectedIndex()].conversionFactor;
票数 6
EN

Code Review用户

发布于 2015-04-21 22:13:43

LengthConverter是做什么的?它会显示按钮,对点击做出反应吗?或者转换长度?

这显然违反了分离关注点原则。只需将转换提取到单独的类。

实际上,Martin .S的Unit已经这么做了,您也可以使用枚举(注释来自隆布克,但是应该是显而易见的)。

代码语言:javascript
复制
@RequiredArgsConstructor @Getter
public enum Unit {
    METER(1.0),
    CENTIMETER(0.01),
    INCH(0.0254),
    FURLONG(201.168),
    ...
    ;

    double convertFrom(double amount, Unit unit) {
        return amount * unit.meters / this.meters;
    }

    private final double meters;
}

有一个类似的表情

代码语言:javascript
复制
Unit.INCH.convertFrom(2, Unit.LIGHT_YEAR);

告诉你有多少英寸等于2光年。不需要地图。

枚举的明显缺点是它们不能被扩展,但是对于作者来说,这是没有问题的(无论如何,有用的单元集是相当有限的)。

票数 2
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/87594

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档