Java之格式化输出实践

 更新时间:2026年04月14日 14:31:03   作者:程序员小橙  
这篇文章主要介绍了Java之格式化输出过程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教

在JavaSe5中,推出了C语言中printf()风格的格式化输出。这不仅使得控制输出的代码更加简单,同时也给与Java开发者对于输出格式与排列更大的控制能力。

今天,我们开始学习Java中的格式化输出。

System.out.format()

由于内容比较简单,我们通过实例来加以说明。项目结构如下:

Java Se5引入的format方法可用于PrintStream或PrintWriter对象,其中也包括System.out对象。

package com.tomhu.format;
public class FormatTest1 { 
         public static void main(String[] args) {
             int x = 5;
             double y = 3.141592;
             // 一般方式 
             System.out.println("x = " + x + ", y = " + y); 
             // printf()方式 System.out.printf("x = %d, y = %f\n", x, y); 
             // format()方式 
             System.out.format("x = %d, y = %f\n", x, y); 
     }
}

输出的结果如下:

x = 5,

y = 3.141592x = 5,

y = 3.141592x = 5,

y = 3.141592

可以看到,format与printf是等价的,它们只需要一个简单的格式化字符串,加上一串参数即可,每个参数对应一个格式修饰符。

public PrintStream printf(String format, Object ... args) {
        return format(format, args);
}

在format的具体代码中,其实就是调用Formatter的format方法:formatter.format(Locale.getDefault(), format, args);

public PrintStream format(String format, Object ... args) {
    try {
        synchronized (this) {
            ensureOpen();
            if ((formatter == null)
                || (formatter.locale() != Locale.getDefault()))
                formatter = new Formatter((Appendable) this);
            formatter.format(Locale.getDefault(), format, args);
        }
    } catch (InterruptedIOException x) {
        Thread.currentThread().interrupt();
    } catch (IOException x) {
        trouble = true;
    }
    return this;
}

Formatter类

在Java中,所有新的格式化功能都由Formatter类处理,上述的printf与format也是。

可以将Formatter看作是一个翻译器,它将你的格式化字符串与数据翻译成需要的结果。

当你创建一个Formatter对象的时候 ,需要向其构造器传递一些信息,告诉它最终的结果将向哪里输出

package com.tomhu.format;import java.util.Formatter;public class FormatTest2 {
    public static void main(String[] args) {
        String name = "huhx";
        int age = 22;       
        Formatter formatter = new Formatter(System.out);
        formatter.format("My name is %s, and my age is %d ", name, age);
        formatter.close();
    }
}

它的输出结果如下:

My name is huhx, and my age is 22

格式化说明符

在插入数据时,如果想要控制空格与对齐,就需要精细复杂的格式修饰符,以下是其抽象的语法:

%[argument_index$][flags][width][.precision]conversion

The optional argument_index is a decimal integer indicating the position of the argument in the argument list. The first argument is referenced by "1$", the second by "2$", etc.

The optional flags is a set of characters that modify the output format. The set of valid flags depends on the conversion.The optional width is a non-negative decimal integer indicating the minimum number of characters to be written to the output.

The optional precision is a non-negative decimal integer usually used to restrict the number of characters.

The specific behavior depends on the conversion.

The required conversion is a character indicating how the argument should be formatted.

The set of valid conversions for a given argument depends on the argument's data type.

最常见的应用是控制一个域的最小尺寸,这可以通过指定width来实现。Formatter对象通过在必要时添加空格,来确保一个域至少达到某个长度。在默认的情况下,数据是右对齐的,通过"-"标志可以改变对齐的方向。

与width相对的是precision(精确度),它用来指明最大尺寸。width可以应用各种类型的数据转换,并且其行为方式都一样。precision则不一样,不是所有类型的数据都能使用precision,而且,应用于不同的类型的数据转换时,precision的意义也不同。

1.precision应用于String时,它表示打印String时输出字符的最大数量

2.precision应用于浮点数时,它表示小数点要显示出来的位数。默认是6位小数,如果小数位数过多则舍入,过少则在尾部补零。

3.由于整数没有小数部分,所以precision不能应用于整数。如果你对整数应用precision,则会触发异常

package com.tomhu.format;import java.util.Formatter;public class FormatTest3 {
    static Formatter formatter = new Formatter(System.out);
    public static void printTitle() {
        formatter.format("%-15s %-5s %-10s\n", "huhx", "linux", "liuli");
        formatter.format("%-15s %-5s %-10s\n", "zhangkun", "yanzi", "zhangcong");
        formatter.format("%-15s %-5s %-10s\n", "zhangkun", "yanzhou", "zhangcong");
    }
    public static void print() {
        formatter.format("%-15s %5d %10.2f\n", "My name is huhx", 5, 4.2);
        formatter.format("%-15.4s %5d %10.2f\n", "My name is huhx", 5, 4.1);
    }   
    public static void main(String[] args) {
        printTitle();
        System.out.println("----------------------------");
        print();
        formatter.close();
    }
}

它的输出结果如下:

huhx linux liuli

zhangkun yanzi zhangcong

zhangkun yanzhou zhangcong

----------------------------

My name is huhx 5 4.20

My n 5 4.10

Formatter转换

下图包含了最常用的类型转换:

String.format()是一个static方法,它接受与Formatter.format()方法一样的参数,但返回一个String对象。

当你只需要用format方法一次的时候,String.format()还是很方便的。

package com.tomhu.format;
public class FormatTest4 {
    public static void main(String[] args) {
        int age = 22;
        String name = "huhx";
        String info = String.format("My name is %s and my age is %d", name, age);
        System.out.println(info);
    }
}

它的输出结果如下:

My name is huhx and my age is 22

其实String.format方法的实质还是Formatter.format(),只不过是做了简单封装而已:

public static String format(String format, Object... args) {
    return new Formatter().format(format, args).toString();
}

简单的十六进制转换工具

package com.tomhu.format;
public class FormatTest5 {
    public static String format(byte[] data) {
        StringBuilder builder = new StringBuilder();
        int n = 0;
        for(byte b: data) {
            if (n %16 == 0) {
                builder.append(String.format("%05x: ", n));
            }
            builder.append(String.format("%02x ", b));
            n ++;
            if (n % 16 == 0) {
                builder.append("\n");
            }
        }
        builder.append("\n");
        return builder.toString();
    }
    public static void main(String[] args) {
        String string = "my name is huhx, welcome to my blog";
        System.out.println(format(string.getBytes()));
    }
}

输出结果如下:

00000: 6d 79 20 6e 61 6d 65 20 69 73 20 68 75 68 78 2c

00010: 20 77 65 6c 63 6f 6d 65 20 74 6f 20 6d 79 20 62

00020: 6c 6f 67

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • Java多线程的sleep休眠的实现

    Java多线程的sleep休眠的实现

    本文主要介绍了Java多线程的sleep休眠的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-06-06
  • java线程池使用及原理面试题

    java线程池使用及原理面试题

    很多面试官喜欢把线程池作为问题的起点,然后延伸到其它内容,由于我们专栏已经说过队列、线程、锁面试题了,所以本章面试题还是以线程池为主
    2022-03-03
  • 一文详解Spring 中的顺序问题

    一文详解Spring 中的顺序问题

    本文主要介绍了Spring 中的顺序问题,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-05-05
  • JavaMail发送(带图片和附件)和接收邮件实现详解(四)

    JavaMail发送(带图片和附件)和接收邮件实现详解(四)

    这篇文章主要为大家详细介绍了JavaMail带图片和附件的发送和接收邮件实现,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-10-10
  • 利用IDEA社区版创建SpringBoot项目的详细图文教程

    利用IDEA社区版创建SpringBoot项目的详细图文教程

    大家应该都知道Idea社区版本,默认是不能创建SpringBoot项目的,下面这篇文章主要给大家介绍了关于利用IDEA社区版创建SpringBoot项目的详细图文教程,文中通过图文介绍的非常详细,需要的朋友可以参考下
    2023-04-04
  • Java Spring boot 配置JDK和MAVEN开发环境的过程

    Java Spring boot 配置JDK和MAVEN开发环境的过程

    本文详细介绍了如何配置JDK和Maven环境,包括JDK的安装与环境变量设置,Maven的下载、配置环境变量和设置阿里云仓库,最后简述了在IntelliJ IDEA中配置JDK和Maven的步骤,本教程适合Java开发新手进行开发环境的搭建,确保顺利进行Java项目的开发
    2024-11-11
  • 详解Spring mvc DispatchServlet 实现机制

    详解Spring mvc DispatchServlet 实现机制

    本篇文章主要介绍了详解Spring mvc DispatchServlet 实现机制,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-09-09
  • Java类中this关键字与static关键字的用法解析

    Java类中this关键字与static关键字的用法解析

    这篇文章主要介绍了Java类中this关键字与static关键字的用法解析,文章围绕主题展开详细的内容介绍,具有一定的参考价值,需要的小伙伴可以参考一下
    2022-09-09
  • JAVA关键字及作用详解

    JAVA关键字及作用详解

    本文主要介绍了Java关键字及作用,具有很好的参考价值,下面跟着小编一起来看下吧
    2017-02-02
  • idea中提示Class 'xxx' is never used的解决

    idea中提示Class 'xxx' is never us

    这篇文章主要介绍了idea中提示Class 'xxx' is never used的解决方案,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-01-01

最新评论