【问题标题】:Formatting numbers with same amount of padding用相同的填充量格式化数字
【发布时间】:2014-11-03 16:16:17
【问题描述】:

我想在 Java 中格式化 3 位浮点数,使它们垂直排列,如下所示:

123.45
 99
 23.2
 45

当我使用 DecimalFormat 类时,我很接近,但我想在项目有 1 位或 2 位数字时插入空格。

我的代码:

DecimalFormat formatter = new java.text.DecimalFormat("####.##");
float [] floats = [123.45, 99.0, 23.2, 45.0];

for(int i=0; i<floats.length; i++)
{
    float value = floats[i];

    println(formatter.format(value));
}

它产生:

123.45
99
23.2
45

我怎样才能打印它,以便除第一行之外的所有内容都移动 1 个空格?

【问题讨论】:

  • 如果有人想谷歌这个,它被称为十进制标签。

标签: java


【解决方案1】:

试试String.format() (JavaDoc):

public static void main(String args[]){
  String format = "%10.2f\n";  // width == 10 and 2 digits after the dot
  float [] floats = {123.45f, 99.0f, 23.2f, 45.0f};
  for(int i=0; i<floats.length; i++) {
      float value = floats[i];
      System.out.format(format, value);
}

输出是:

123.45
 99.00
 23.20
 45.00

【讨论】:

    【解决方案2】:

    这对于一些正则表达式字符串替换来说是微不足道的。

    formatter.format(f).replaceAll("\\G0", " ")
    

    这里是上下文:(see also on ideone.com):

        DecimalFormat formatter = new java.text.DecimalFormat("0000.##");
        float[] floats = {
            123.45f,     //  123.45
             99.0f,      //   99
             23.2f,      //   23.2
             12.345f,    //   12.35
               .1234f,   //     .12
            010.001f,    //   10
        };
    
        for(float f : floats) {
            String s = formatter.format(f).replaceAll("\\G0", " ");
            System.out.println(s);
        }
    

    这使用DecimalFormat 进行大部分格式化(零填充、可选的# 等),然后使用String.replaceAll(String regex, String replacement) 将所有前导零替换为空格。

    正则表达式模式是\G0。也就是说,0 前面是 \G,这是“上一场比赛的结束”锚点。 \G 也出现在字符串的开头,这就是允许前导零(而不是其他零)匹配并替换为空格的原因。

    参考文献


    关于转义序列

    模式\G0 写成"\\G0" 作为Java 字符串文字的原因是因为反斜杠是转义字符。也就是说,"\\" 是一个长度为 1 的字符串,包含反斜杠。

    参考文献

    相关问题


    其他提示

    请注意,我使用了for-each 循环,这使得代码更加简单,从而提高了可读性并最大限度地减少了出错的机会。我还将浮点变量保留为float,使用f 后缀将它们声明为float 文字(因为它们默认为double),但需要说明的是,通常你应该更喜欢double 而不是float

    另见

    【讨论】:

    • 它没有说明问题中需要什么,但这个解决方案不会为数字 0f 打印任何内容
    • 此外,如果您需要使用逗号等其他内容来分隔千位,则此解决方案将不起作用。
    【解决方案3】:

    只需更改您的第一行,将“#”字符替换为“0”。它将解决您的问题并生成具有相同长度的格式化数字,如@9​​87654321@ 中所述。使用该方法,您的行将以附加的“0”数字开头和结尾(例如 099.00):

    DecimalFormat formatter = new java.text.DecimalFormat("0000.00");
    

    如果您想要正确对齐而不需要这些无用的“0”,则必须创建自己的格式化方法:它在本机 Java API 中不存在。

    【讨论】:

    • 这会导致额外的前导零打印在前面,例如:099.0 但我想要的是 [space]99.0
    【解决方案4】:

    与 Benoit 的回答一样,这是一个扩展 DecimalFormat 的类,它通过用空格左填充格式化数字来确保指定的最小长度。它已经过测试(Java 6、7),更通用,并提供了一个工作示例。

    import java.text.DecimalFormat;
    import java.text.DecimalFormatSymbols;
    import java.text.FieldPosition;
    
    public class PaddingDecimalFormat extends DecimalFormat {
        private int minimumLength;
    
        /**
         * Creates a PaddingDecimalFormat using the given pattern and minimum minimumLength and the symbols for the default locale.
         */
        public PaddingDecimalFormat(String pattern, int minLength) {
            super(pattern);
            minimumLength = minLength;
        }
    
        /**
         * Creates a PaddingDecimalFormat using the given pattern, symbols and minimum minimumLength.
         */
        public PaddingDecimalFormat(String pattern, DecimalFormatSymbols symbols, int minLength) {
            super(pattern, symbols);
            minimumLength = minLength;
        }
    
        @Override
        public StringBuffer format(double number, StringBuffer toAppendTo, FieldPosition pos) {
            int initLength = toAppendTo.length();
            super.format(number, toAppendTo, pos);
            return pad(toAppendTo, initLength);
        }
    
        @Override
        public StringBuffer format(long number, StringBuffer toAppendTo, FieldPosition pos) {
            int initLength = toAppendTo.length();
            super.format(number, toAppendTo, pos);
            return pad(toAppendTo, initLength);
        }
    
        private StringBuffer pad(StringBuffer toAppendTo, int initLength) {
            int numLength = toAppendTo.length() - initLength;
            int padLength = minimumLength - numLength;
            if (padLength > 0) {
                StringBuffer pad = new StringBuffer(padLength);
                for(int i = 0; i < padLength; i++) {
                    pad.append(' ');
                }
                toAppendTo.insert(initLength, pad);
            }
            return toAppendTo;
        }
    
        public static void main(String[] args) {
            PaddingDecimalFormat intFormat = new PaddingDecimalFormat("#", 6);
            for (int i = 0; i < 20; i++) {
                System.out.println(intFormat.format(i) + intFormat.format(i*i*i));
            }
        }
    }
    

    【讨论】:

      【解决方案5】:

      一个应该回答你的问题的方法(我直接在这里写了它,没有测试它,所以你可能有一些错误需要纠正,但至少,你明白了):

      public class PaddingDecimalFormat extends DecimalFormat {
      
          private int maxIntLength = 1;
      
          public PaddingDecimalFormat(String pattern) {
              super(pattern);
          }
      
          public void configure(Number[] numbers) {
              for(Number number : numbers) {
                   maxIntLength = Math.max(maxIntLength, Integer.toString(number.intValue()).length()); 
              }
          }
      
          @Override
          public void format(Number number) {
              int padding = maxIntLength - Integer.toString(number.intValue()).length();
      
              StringBuilder sb = new StringBuilder();
      
              for(int i=0; i<padding; i++) {
                  sb.append(' ');
              }
      
              sb.append(super.format(number));
      
              return sb.toString();
          }
      }
      

      【讨论】:

      • 也许这适用于早于 6 的 Java 版本,但不适用于 Java 6 或 7。我使用更灵活且经过测试的类似方法添加了另一个答案使用 Java 6+。
      【解决方案6】:

      想象一下分号和 System.out。像上面有问题的格式化程序。

      printf ("   ".substring (("" + Math.round (f)).length ) + formatter.format (f))
      

      我更喜欢 log-10-Function 来计算 999 或 100 到 3 的大小,而不是隐式的 toString 调用,但我只找到自然对数。

      Math.round (987.65) 得到 987。
      ("" + 987).length 给出 3
      "___".substring (3) 是空字符串,对于短数字 (0-9),它将返回两个空格。

      【讨论】:

        猜你喜欢
        • 2011-07-21
        • 2019-08-27
        • 2017-06-26
        • 1970-01-01
        • 1970-01-01
        • 2010-11-18
        • 2020-04-15
        • 1970-01-01
        • 2022-11-18
        相关资源
        最近更新 更多