Java - 如何将数字格式化为两个字符的字符串?

24

如何将介于099之间的整数格式化为一个长度为2的字符串。例如:

4  becomes "04"
36 becomes "36"

提前感谢。

3个回答

54

使用 String.format()。 示例:

class Test{
    public static void main(String[]args){
        System.out.println(String.format("%02d", 42)); //42
        System.out.println(String.format("%02d",  7)); //07
    }
}

编辑:

看到luiscubal的评论,我开始思考,所以我想为什么不对这三个替代方案进行基准测试呢。

import java.text.*;

interface Fmt{
    public String f(int x);
}

class Test{

    static NumberFormat formatter = new DecimalFormat("00");

    static Fmt f1 = new Fmt(){
        public String f(int x){ return ((x<10)?"0":"") + x; }
        public String toString(){return "f1";}
    };

    static Fmt f2 = new Fmt(){
        public String f(int x){ return String.format("%02d", x); }
        public String toString(){return "f2";}
    };

    static Fmt f3 = new Fmt(){
        public String f(int x){ return formatter.format(x); }
        public String toString(){return "f3";}
    };

    public static void main(String[]args){

        Fmt[] fmts = new Fmt[]{f1, f2, f3, f3, f2, f1};

        for (int x : new int[]{7, 42, 99}){

            String s0 = null;
            for (Fmt fmt : fmts)
                if (s0==null)
                    s0 = fmt.f(x);
                else
                    if (!fmt.f(x).equals(s0))
                        System.exit(1);

            System.out.printf("%02d\n", x);

            for (Fmt fmt : fmts){
                String s = null;
                int count = 0;
                System.gc();
                long t0 = System.nanoTime();
                for (int i=0; i<100000; i++){
                    count += fmt.f(x).length();
                }
                long t1 = System.nanoTime();

                System.out.printf("    %s:%8.2fms, count=%d\n",
                    fmt, (t1-t0)/1000000.0, count);
            }

        }
    }

}

我得到的输出是:

07
    f1:   11.28ms, count=200000
    f2:  195.97ms, count=200000
    f3:   45.41ms, count=200000
    f3:   39.67ms, count=200000
    f2:  164.46ms, count=200000
    f1:    6.58ms, count=200000
42
    f1:    5.25ms, count=200000
    f2:  163.87ms, count=200000
    f3:   42.78ms, count=200000
    f3:   42.45ms, count=200000
    f2:  163.87ms, count=200000
    f1:    5.15ms, count=200000
99
    f1:    5.83ms, count=200000
    f2:  168.59ms, count=200000
    f3:   42.86ms, count=200000
    f3:   42.96ms, count=200000
    f2:  165.48ms, count=200000
    f1:    5.22ms, count=200000

结果表明,如果我测试正确的话,SpeedBirdNine提供了最有效的解决方案,尽管表达得不好。因此,我修改了我的解决方案为:

String answer = ((x<10)?"0":"") + x;

回想起来,我认为这是有道理的,因为我的初始解决方案涉及解析格式字符串的成本,我假设Anthony的格式化程序也有某种数据结构,在每次迭代时都会被迭代。

如果使用包含所有100个字符串的String[],速度可预见地更快,但可能有点过头了...


如果性能是主要问题,我认为不应该使用Java - 我非常确定,因为这里的应用程序是一些字符串格式化,性能显然不是主要问题。在这种情况下,Java的主要优势是其全面的标准库,具有诸如我在上面评论中强调的功能:支持国际化和本地化。 - Anthony Blake
我自己也使用过格式化程序,出于你提到的原因,这就是为什么我会点赞你的评论。我并不是想通过我的基准测试来证明什么,而是好奇那些替代方案如何相互配合。但我确实认为,在Java内部循环中有数字格式化代码的合法用例可能存在,所以我展示了我的结果。 - Vlad
我同意 - 我已经好几年没有使用Java了,但是我看到它在像Android这样的平台上被广泛使用,那里可能存在优化的情况。有趣的是,String.format()具有很大的开销,它可能会在每次调用时实例化NumberFormat的一个实现。 - Anthony Blake
你说得对。String.format() 实例化了一个 Formatter,然后就是一个相当复杂的过程。我认为其中还涉及到 NumberFormat。有一些巨大的 switch 语句、拆箱操作和边缘情况等。 - Vlad

7
您可以使用NumberFormat来实现此功能。例如,
NumberFormat formatter = new DecimalFormat("00");
String s = formatter.format(4); 

我会使用Vlad的答案,因为它很简短 :) - Ash Burlaczenko
1
请记住 NumberFormat -- 当涉及国际化和本地化时,您可能需要使用它而不是字符串格式化程序。 - Anthony Blake

3

将 "" 添加到整数(或任何基本类型)后面是一种简单的方法。

String str = "" + anyInetger;

您可以使用

标签


String str;
if (anyInteger < 10)
{
    str = " 0" + anyInetger;
}
else
{
    str = "" + anyInetger;
}

值得注意的是,您的示例将在整数后添加一个额外的空格,该整数拼写错误,并且我很难相信将空字符串与整数连接起来是将该整数转换为字符串的最佳方法。 - luiscubal
@luiscubal 这比 Integer.toString(i); 或使用 new StringBuffer(3).append('0').append(i).substring(i<10?0:1,i<10?2:3); 更简洁。 - ratchet freak
@luiscubal 还要注意的是,在 if-else 之后 str 是不可见的。虽然效率很高,但还是要加1分。 - Vlad
@Vlad 是的,我没有看到那一个。 - luiscubal

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接