使用 MessageFormat 创建一个 ASCII 温度计

Create an ASCII thermometer using MessageFormat

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

目前我在 14 个参数中的每一个中都使用类似的 if 语句,然后确定它是否应该在所述位置添加星号 temp >= location 或空 space 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) ? "*" : " "));

你想要这个吗?

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  |
     |         ***`       |
     |       (*****)      |
     |        `---        |
     |____________________|

由于您正在尝试 绘制图像 而不是打印 String 我建议您创建一个负责该图像的 class,即AsciiImageThermometerPrinter。那class就能print()一定的温度状态

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

至于创建输出,我会使用 line-based 中间部分绘制 line-by-line 温度计,一部分用于 header,一部分用于 bottom-part。

会有什么不同?

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

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

你的代码会更可靠。