网站首页 > 精选教程 正文
8. 使用变量/表达式格式化文本块
在Java中,使用变量/表达式格式化字符串字面量以获取动态字符串是一种常见的做法。例如,我们可以通过众所周知的连接符“+”来创建一个动态的JSON字符串片段,如下所示:
String fn = "Jo";
String ln = "Kym";
String str = "<user><firstName>" + fn
+ "</firstName><lastName>" + ln + "</lastName></user>";
// 输出
<user><firstName>Jo</firstName><lastName>Kym</lastName></user>
当然,从可读性的角度来看,这个简单的构造存在严重的问题。如果JSON代码按照格式和缩进进行格式化,那么它就是人类可读的,否则真的很难跟踪其层次结构。那么,我们能否将这段JSON表示为如下图的格式呢?
图1.6 - 格式化的JSON
当然可以!通过使用一些转义序列(例如,\n、\t、\s),空格等,我们可以构造一个看起来像图1.6的字符串。但是,通过文本块来表示这种连接会更好。也许我们可以在IDE的代码编辑器和IDE的控制台(在运行时)中获得相同的可读性。一种可能的方法如下所示:
String json = """
<user>
<firstName>\
"""
+ fn
+ """
</firstName>
<lastName>\
"""
+ ln
+ """
</lastName>
</user>
""";
所以,我们可以通过"+"运算符将文本块与字符串字面量一样进行连接。酷!这段代码的输出对应于图1.6的左侧。另一方面,图1.6的右侧可以通过以下方式实现:
String json = """
<user>
<firstName>
"""
+ fn.indent(4) // 注意这里indent方法不是JDK自带的,可能是自定义的
+ """
</firstName>
<lastName>
"""
+ ln.indent(4)
+ """
</lastName>
</user>
""";
虽然结果字符串在这两种情况下看起来都很好,但我们不能对代码本身说同样的话。它的可读性仍然很低。
通过查看前两个代码片段,我们可以很容易地总结出文本块的一个最佳实践:仅当文本块显著有助于代码的清晰性和多行字符串的可读性时才使用它们。另外,避免在复杂表达式(例如,在lambda表达式中)中声明文本块,因为它们可能会影响整个表达式的可读性。最好将文本块单独提取到静态变量中,并在复杂表达式中引用它们。
让我们尝试另一种方法。这次,让我们使用StringBuilder来获取图1.6左侧的结果:
StringBuilder sbJson = new StringBuilder();
sbJson.append("""
<user>
<firstName>""")
.append(fn)
.append("""
</firstName>
<lastName>""")
.append(ln)
.append("""
</lastName>
</user>""");
获取图1.6右侧的结果可以这样做:
StringBuilder sbJson = new StringBuilder();
sbJson.append("""
<user>
<firstName>
""")
.append(fn.indent(4))
.append("""
</firstName>
<lastName>
""")
.append(ln.indent(4))
.append("""
</lastName>
</user>
""");
所以,我们可以在StringBuilder/StringBuffer中使用文本块,就像我们使用字符串字面量一样。虽然结果字符串对应于图1.6中的示例,但代码本身从可读性的角度来看仍然不尽如人意。
让我们再通过JDK 1.4的MessageFormat.format()来尝试一下。首先,让我们根据图1.6左侧的例子来格式化:
String json = MessageFormat.format("""
<user>
<firstName>{0}</firstName>
<lastName>{1}</lastName>
</user>
""", fn, ln);
获取图1.6右侧的结果可以这样做:
String json = MessageFormat.format("""
<user>
<firstName>
{0}
</firstName>
<lastName>
{1}
</lastName>
</user>
""", fn, ln);
文本块和MessageFormat.format()的组合是一个成功的做法。代码可读性显然更好。但是,让我们更进一步,并在JDK 5的String.format()中尝试一下。和往常一样,我们先展示图1.6左侧的例子:
String json = String.format("""
<user>
<firstName>%s</firstName>
<lastName>%s</lastName>
</user>
""", fn, ln);
获取图1.6右侧的结果可以这样做:
String json = """
<user>
<firstName>
%s
</firstName>
<lastName>
%s
</lastName>
</user>
""".formatted(fn, ln);
文本块和String.format()的组合是另一种成功的做法,但并不是我们可以利用的最新特性。从JDK 15开始,String.format()有一个更方便的伴侣名为formatted()。以下是使用String.formatted()来复制图1.6左侧的例子:
String json = """
<user>
<firstName>%s</firstName>
<lastName>%s</lastName>
</user>
""".formatted(fn, ln);
获取图1.6右侧的结果可以这样做:
String json = """
<user>
<firstName>
%s
</firstName>
<lastName>
%s
</lastName>
</user>
""".formatted(fn, ln);
好吧,我们能做的最好的就是这样了。我们设法在IDE的代码编辑器和包含动态部分(变量)的文本块的运行时达到了相同的可读性水平。很酷,不是吗?从性能的角度来看,你可以在捆绑的代码中找到这些方法的基准测试。在下图中,你可以看到在配备Windows 10的Intel(R) Core(TM) i7-3612QM CPU @ 2.10GHz机器上的基准测试结果,但请随意在不同的机器上进行测试,因为结果高度依赖于机器。
图1.7 - 基准测试结果
根据这些结果,通过"+"运算符的连接是最快的,而MessageFormat.format()是最慢的。
猜你喜欢
- 2024-10-28 Java 8 中处理日期和时间示例 java 日期时间格式
- 2024-10-28 Java 实现日期的格式化,月份和天不足两位时补上0
- 2024-10-28 Java中日期格式化YYYY-DD的坑 java 日期格式化为yyyy-mm-dd mmss
- 2024-10-28 Java 的流程控制是什么样子的 java流程控制有哪些
- 2024-10-28 Java优雅的保留两位小数 java保留两位数字
- 2024-10-28 阿里面试官:聊聊如何格式化 Instant
- 2024-10-28 圆你的大厂梦!今日头条Java高频面试题真题:一/二/三面+常见问题
- 2024-10-28 “全栈2019”Java第十四章:二进制、八进制、十六进制
- 2024-10-28 Java,FreeMarker,模板引擎,通过案例代码,学懂模板引擎
- 2024-10-28 Springboot强大的数据格式化功能你必须要知道
你 发表评论:
欢迎- 最近发表
- 标签列表
-
- nginx反向代理 (57)
- nginx日志 (56)
- nginx限制ip访问 (62)
- mac安装nginx (55)
- java和mysql (59)
- java中final (62)
- win10安装java (72)
- java启动参数 (64)
- java链表反转 (64)
- 字符串反转java (72)
- java逻辑运算符 (59)
- java 请求url (65)
- java信号量 (57)
- java定义枚举 (59)
- java字符串压缩 (56)
- java中的反射 (59)
- java 三维数组 (55)
- java插入排序 (68)
- java线程的状态 (62)
- java异步调用 (55)
- java中的异常处理 (62)
- java锁机制 (54)
- java静态内部类 (55)
- java怎么添加图片 (60)
- java 权限框架 (55)
本文暂时没有评论,来添加一个吧(●'◡'●)