【问题标题】:Create an ASCII thermometer using MessageFormat使用 MessageFormat 创建 ASCII 温度计
【发布时间】:2019-02-15 05:48:43
【问题描述】:

我正在使用 Java 的 MessageFormat 类创建一个字符串,该字符串使用 format 方法将多个条件语句作为参数。有了它,我创建了一个使用 ASCII 字符的温度计,它接受一个随机数作为摄氏度,并根据该数字,根据条件在特定位置将星号字符插入到字符串中,例如((celsius >= 25) ? "*" : " ")。换句话说,星号代表温度计中的温度水平,具体取决于温度值。

目前,我在 14 个参数中的每一个参数中都使用了类似的 if 语句,然后确定是否应该在所述位置 temp >= location 或空格 temp <= location 中添加星号。我确信使用另一种方法可以更有效和更清洁地执行此操作,例如内嵌for循环、正则表达式、函数、内置方法等

这是代码示例(注意转义字符):

// random value between -35 and 40
double celsius = Math.round(Math.random() * (40 - 35) - 35);

// ASCII Thermometer
String meter = MessageFormat.format(
                "     ______________________"
                + "\r\n     |   ^F     _    ^C   |"
                + "\r\n     |  100  - |{0}| -  40  |"
                + "\r\n     |   90  - |{1}| -  30  |"
                + "\r\n     |   80  - |{2}| -  25  |"
                + "\r\n     |   70  - |{3}| -  20  |"
                + "\r\n     |   60  - |{4}| -  15  |"
                + "\r\n     |   50  - |{5}| -  10  |"
                + "\r\n     |   40  - |{6}| -   5  |"
                + "\r\n     |   30  - |{7}| -   0  |"
                + "\r\n     |   20  - |{8}| -  -5  |"
                + "\r\n     |   10  - |{9}| - -10  |"
                + "\r\n     |    0  - |{10}| - -20  |"
                + "\r\n     |  -10  - |{11}| - -25  |"
                + "\r\n     |  -20  - |{12}| - -30  |"
                + "\r\n     |  -30  - |{13}| - -35  |"
                + "\r\n     |         '***`       |"
                + "\r\n     |       (*****)      |"
                + "\r\n     |        `---'        |"
                + "\r\n     |____________________|"
                + "\r\n\r\n",
        ((celsius >= 35) ? "*" : " "),
        ((celsius >= 30) ? "*" : " "),
        ((celsius >= 25) ? "*" : " "),
        ((celsius >= 20) ? "*" : " "),
        ((celsius >= 15) ? "*" : " "),
        ((celsius >= 10) ? "*" : " "),
        ((celsius >= 5) ? "*" : " "),
        ((celsius >= 0) ? "*" : " "),
        ((celsius >= -5) ? "*" : " "),
        ((celsius >= -10) ? "*" : " "),
        ((celsius >= -15) ? "*" : " "),
        ((celsius >= -20) ? "*" : " "),
        ((celsius >= -25) ? "*" : " "),
        ((celsius >= -30) ? "*" : " "));

【问题讨论】:

    标签: java ascii-art messageformat


    【解决方案1】:

    你想要这个吗?

    public static void main(String[] args) {
        // random value between -35 and 40
        double celsius = Math.round(Math.random() * (40 - 35) - 35);
    
        final String s = "     ______________________"
                + "\r\n     |   ^F     _    ^C   |"
                + "\r\n     |  100  - |{0}| -  40  |"
                + "\r\n     |   90  - |{1}| -  30  |"
                + "\r\n     |   80  - |{2}| -  25  |"
                + "\r\n     |   70  - |{3}| -  20  |"
                + "\r\n     |   60  - |{4}| -  15  |"
                + "\r\n     |   50  - |{5}| -  10  |"
                + "\r\n     |   40  - |{6}| -   5  |"
                + "\r\n     |   30  - |{7}| -   0  |"
                + "\r\n     |   20  - |{8}| -  -5  |"
                + "\r\n     |   10  - |{9}| - -10  |"
                + "\r\n     |    0  - |{10}| - -20  |"
                + "\r\n     |  -10  - |{11}| - -25  |"
                + "\r\n     |  -20  - |{12}| - -30  |"
                + "\r\n     |  -30  - |{13}| - -35  |"
                + "\r\n     |         '***`       |"
                + "\r\n     |       (*****)      |"
                + "\r\n     |        `---'        |"
                + "\r\n     |____________________|";
    
        final int[] celsiusDegreeCompare = new int[]{
                35, 30, 25, 20, 15, 10, 5, 0, -5, -10, -20, -25, -30, -35
        };
    
        final String[] parameters = new String[14];
    
        IntStream.range(0, parameters.length).forEach(i -> {
            parameters[i] = (celsius >= celsiusDegreeCompare[i]) ? "*" : " ";
        });
    
        // ASCII Thermometer
        String meter = MessageFormat.format(s, parameters);
    
        System.out.println("celsius: " + celsius);
        System.out.println(meter);
    }
    

    结果:

    celsius: -31.0
         ______________________
         |   ^F     _    ^C   |
         |  100  - | | -  40  |
         |   90  - | | -  30  |
         |   80  - | | -  25  |
         |   70  - | | -  20  |
         |   60  - | | -  15  |
         |   50  - | | -  10  |
         |   40  - | | -   5  |
         |   30  - | | -   0  |
         |   20  - | | -  -5  |
         |   10  - | | - -10  |
         |    0  - | | - -20  |
         |  -10  - | | - -25  |
         |  -20  - | | - -30  |
         |  -30  - |*| - -35  |
         |         ***`       |
         |       (*****)      |
         |        `---        |
         |____________________|
    

    【讨论】:

      【解决方案2】:

      由于您尝试绘制图像而不是打印String,因此我建议您创建一个负责该操作的类,即AsciiImageThermometerPrinter。该类将能够print() 某种温度状态。

      要构建您的String,我建议使用StringBuilder 而不是MesssgeFormat

      至于创建输出,我将使用基于行的中间部分,逐行绘制温度计,一部分用于标题,另一部分用于底部。

      会有什么不同?

      您可以简单地提供具有不同范围和单位的温度计。您只需提供更长或更短的温度计。

      您的代码将是可测试的,其他开发人员会更容易理解您的代码。

      您的代码会更可靠。

      【讨论】:

      • 很抱歉,答案是用我的手机写的。稍后,当我在办公室时,我将为StringBuilder 部分提供一些示例。
      猜你喜欢
      • 2011-12-28
      • 2012-10-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多