System.out.printf使用以及注意点
一、System.out.printf格式化输出
1、常用控制符
|
控制符 |
说明 |
|
%d |
按十进制整型数据的实际长度输出。 |
|
%ld |
输出长整型数据。 |
|
%md |
m 为指定的输出字段的宽度。如果数据的位数小于 m,则左端补以空格,若大于 m,则按实际位数输出。 |
|
%u |
输出无符号整型(unsigned)。输出无符号整型时也可以用 %d,这时是将无符号转换成有符号数,然后输出。但编程的时候最好不要这么写,因为这样要进行一次转换,使 CPU 多做一次无用功。 |
|
%c |
用来输出一个字符。 |
|
%f |
用来输出实数,包括单精度和双精度,以小数形式输出。不指定字段宽度,由系统自动指定,整数部分全部输出,小数部分输出 6 位,超过 6 位的四舍五入。 |
|
%.mf |
输出实数时小数点后保留 m 位,注意 m 前面有个点。 |
|
%o |
以八进制整数形式输出,这个就用得很少了,了解一下就行了。 |
|
%s |
用来输出字符串。用 %s 输出字符串同前面直接输出字符串是一样的。但是此时要先定义字符数组或字符指针存储或指向字符串,这个稍后再讲。 |
|
%x(或 %X 或 %#x 或 %#X) |
以十六进制形式输出整数,这个很重要。 |
代码演示:
public static void main(String[] args) {
2 //最常用的主要是三个:字符串 %s, 整型%d, 浮点型保留小数位%.mf(m表示小数点后m位), \n表示换行符
3 System.out.printf("*学生资料*\n 姓名:%s\n 年龄:%d岁\n 考试成绩(保留两位小数): %.2f\n",
"小明", 15, 98.456);
4 }
控制台显示:

另外System.out.printf有一定程度的输出格式化效果

输出结果:

如果 使用System.out.print(ln)格式就出现了明显不同


2、示例代码
package system.out; public class Printf
{ public static void main(String[] args)
{
//%代表格式化
//f代表输出浮点数,9代表输出长度,如果浮点数长度不足,则补空格,如果浮点数长度超出,则按实际长度输出,2代表保留小数点后几位小数
System.out.printf("%9.2f",1111.3);
System.out.println();
//-号代表向左对齐,默认向右对齐
System.out.printf("%-9.2f", 1111.3);
System.out.println();
//+号代表显示正负号
System.out.printf("%+9.2f", 1111.3);
System.out.println();
//+-号代表显示正负号,且向左对齐
System.out.printf("%+-9.2f", 1111.3);
System.out.println();
//d代表输出整数
System.out.printf("%4d",15);
System.out.println();
//o代表输出8进制整数
System.out.printf("%-4o",15);
System.out.println();
//x代表输出16进制整数
System.out.printf("%-4x",15);
System.out.println();
//#x代表输出带有16进制标志的整数
System.out.printf("%#x",15);
System.out.println();
//s代表输出字符串
System.out.printf("%-8s", "我们是中心");
System.out.println();
//x$,整数加$表示第几个变量,如果不加,变量按默认顺序排列
System.out.printf("%2$-5s:夺得世界杯总冠军,进球数:%1$3d,对方进球:%3$2d", 4,"法国",2);
}
}
二、看下底层代码实现
public PrintStream printf(String format, Object ... args) {
return format(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;
}
可以看到和String.format底层实现类似调用Formatter()类的format方法。
public static String format(String format, Object... args) {
return new Formatter().format(format, args).toString();
}
三、接下来分析下 String.format与StringBuilder与String +比较
1、测试代码:
class StringTest {
public static void main(String[] args) {
// testOperatorPlus();
//testAppend();
testFormat();
}
private static void testFormat() {
Runtime runtime = Runtime.getRuntime();
long memory;
long prev_time;
int i;
long time;
StringBuilder sb = new StringBuilder();
memory = runtime.freeMemory();
prev_time = System.currentTimeMillis();
for (i = 0; i < 10000; i++) {
String s = String.format("Blah %d Blah %d Blah %d", i, i, i);
}
long ww=runtime.freeMemory();
time = System.currentTimeMillis() - prev_time;
memory = memory - ww;
System.out.println("Time: " + time + " Memory Usage: " + memory);
}
private static void testAppend() {
Runtime runtime = Runtime.getRuntime();
long memory;
long prev_time;
int i;
long time;
StringBuilder sb = new StringBuilder();
memory = runtime.freeMemory();
prev_time = System.currentTimeMillis();
for (i = 0; i < 10000; i++) {
sb.append("Blah ");
sb.append(i);
sb.append("Blah ");
sb.append(i);
sb.append("Blah ");
sb.append(i);
}
time = System.currentTimeMillis() - prev_time;
memory = memory - runtime.freeMemory();
System.out.println("Time: " + time + " Memory Usage: " + memory);
}
private static void testOperatorPlus() {
Runtime runtime = Runtime.getRuntime();
long memory;
long prev_time;
int i;
long time;
StringBuilder sb = new StringBuilder();
memory = runtime.freeMemory();
prev_time = System.currentTimeMillis();
for (i = 0; i < 1000000; i++) {
String s = "Blah " + i + "Blah " + i + "Blah " + i;
}
time = System.currentTimeMillis() - prev_time;
memory = memory - runtime.freeMemory();
System.out.println("Time: " + time + " Memory Usage: " + memory);
}
}
结果如下
| Method | Time(ms) | Memory Usage(long) |
| ‘+’ operator | 102 | 44053736 |
| StringBuilder.append | 6 | 884768 |
| String.foramt | 110 | 22639000 |
StringBuilder.append的执行时间和内存占用都是最优的。'+'运算符比直接调用StringBuilder.append要慢上不少,特别是要连接的字符串数量较多时,内存占用也特别大。String.format由于每次都有生成一个Formatter对象,较慢也是情理之中。public static String format(String format, Object... args) {
return new Formatter().format(format, args).toString();
}
public Formatter() {
this(Locale.getDefault(Locale.Category.FORMAT), new StringBuilder());
}
四、由此引发的优化探讨
在编码中 System.out.println将对象结果输出到控制台,会花费大量的CPU资源,因此发布的代码中不要包含System.out.println 或 System.out.printf。
使用日志框架代替,生产环境注意控制输出级别。
logger.debug("Processing trade with id: " + id + " symbol: " + symbol);
字符串拼接,这样会产生很多String对象,占用空间,影响性能。
另外关于日志输出其他建议:
1、使用[]进行参数变量隔离
如有参数变量,应该写成如下写法:
logger.debug("Processing trade with id:[{}] and symbol : [{}] ", id, symbol);
public List listByBaseType(Integer baseTypeId) {
log.info("开始查询基地");
BaseExample ex=new BaseExample();
BaseExample.Criteria ctr = ex.createCriteria();
ctr.andIsDeleteEqualTo(IsDelete.USE.getValue());
Optionals.doIfPresent(baseTypeId, ctr::andBaseTypeIdEqualTo);
log.info("查询基地结束");
return baseRepository.selectByExample(ex);
}
对于复杂的业务逻辑,需要进行日志打点,以及埋点记录,比如电商系统中的下订单逻辑,以及OrderAction操作(业务状态变更)。
调用其他第三方服务时,所有的出参和入参是必须要记录的(因为你很难追溯第三方模块发生的问题)
3、 生产环境需要关闭DEBUG信息
如果在生产情况下需要开启DEBUG,需要使用开关进行管理,不能一直开启。
System.out.printf使用以及注意点的更多相关文章
- 使用System.out.printf()输出日志重定向到文件后显示混乱问题
写了一个小工具,使用System.out.printf()输出日志,以方便使用者查看,在终端显示没有问题,但重定向到文件就有问题了,会出现一些很奇怪的乱序现象. 上网查询资料,判断应该是跟重定向和Li ...
- java输出格式-----System.out.printf()
package com.lzc.test; public class Main { public static void main(String[] args) { // 定义一些变量,用来格式化输出 ...
- system.out.printf()的使用方法
package com.lzc.test; public class Main { public static void main(String[] args) { // 定义一些变量,用来格式化输出 ...
- java system.out.printf()的使用方法
package test; public class Main { public static void main(String[] args) { // 定义一些变量,用来格式化输出. double ...
- 控制台输出(System.out.printf)的使用
一. 介绍 System.out.printf 与 C语言中的 printf 使用方法类似,可以向控制台(Console) 输出指定格式的内容.使用 System.out.printf 的方法比使 ...
- 与C中printf并列的System.out.printf 用法(转载)
转载地址: https://blog.csdn.net/qq_39017218/article/details/80042287 printf的格式控制的完整格式: % - 0 m.n l或h ...
- java的print,printf,println以及输入
java中有三种方式向控制台输入信息,分别是print,printf,println,现在简单介绍一下他们之间的异同. printf主要是继承了C语言的printf的一些特性,可以进行格式化输出 pr ...
- printf()输出
printf()函数是式样化输出函数, 一般用于向准则输出设备按规定式样输出消息.正在编写步骤时经常会用到此函数.printf()函数的挪用式样为: printf("<式样化字符串&g ...
- JAVA 之print,printf,println
print:将它的参数显示在命令窗口,并将输出光标定位在所显示的最后一个字符之后. println: 将它的参数显示在命令窗口,并在结尾加上换行符,将输出光标定位在下一行的开始. printf:是格式 ...
随机推荐
- 安装Java环境
一.下载JDK https://www.oracle.com/technetwork/java/javase/downloads/index.html 二.exe安装 默认路径 C:\Program ...
- 什么是浮点型?什么是单精度浮点数(float)以及双精度浮点数(double)?
前言 作为一名java学习者,怎能不懂这些java基础中的基础呢?本文就带各位温顾温顾java浮点型.单精度浮点数.双精度浮点数. 浮点型 首先明确java中浮点型数据类型主要有:单精度float.双 ...
- NOIP模拟18 T2
不知道为什么很多人拒绝这题打搜索...其实搜索在充分剪枝后时间是非常优秀的,不管数据怎样基本都可跑出 首先一个显然结论:对于某种状态,他抓到的小精灵一定是一个连续的区间. 因此我们可以枚举这个区间的左 ...
- 用python实现你的绘画梦想
导语: 你是否还在为当时年少时没有选择自己的梦想而伤心,是否还在为自己的无法成为绘画名家而苦恼,这一切都不需要担心.python都能帮你实现,诶!python怎么能画画呢,一些简单的图案没问题,但 ...
- wangkoala杂题总集(根据个人进度选更)
CQOI2014 数三角形 首先一看题,先容斥一波,求出网格内选三个点所有的情况,也就是C(n*m,3);然后抛出行里三点共线的方案数:C(n,3)*m; 同理就有列中三点共线的方案数:n*C(m,3 ...
- 『题解』洛谷P5015 标题统计
题意描述 给你一个字符串,求所有字符的总数. 字符只包含数字,大小写字母. 分析 字符串的长度还是\(\le5\)的. 直接枚举就可以了. AC代码: NOIP官方标准程序是这样的 #include ...
- 小白学 Python(22):time 和 calendar 模块简单使用
人生苦短,我选Python 前文传送门 小白学 Python(1):开篇 小白学 Python(2):基础数据类型(上) 小白学 Python(3):基础数据类型(下) 小白学 Python(4):变 ...
- hexo搭建简易的博客网站
0.环境检测 1.系统升级(图形更新) #update-manager 检测状态 2.检测升级(命令更新) #sudo apt update #sudo apt -y dist-upgrade 一.安 ...
- getClass()和instanceof以及类的equals方法
在比较两个类时,常见有两种做法,一种是x.getClass() == y; 一种是x instanceof y,下面我们来比较这两种做法的区别. getClass()返回一个对象所属的类 public ...
- jdk8 函数式编程概念
yls 2019/11/7 函数式接口 如果一个接口只有一个抽象方法,那么该接口就是函数式接口 如果我们在某接口上声明了FunctionalInterface注解,那么编译器就会按照函数式接口的定义来 ...