在日常寫Java的時候,對於字元串的操作是非常普遍的,其中最常見的就是對字元串的組織。也因為這個操作非常普遍,所以誕生了很多方案,總下來大概有這麼幾種: - 使用`+`拼接 - 使用`StringBuffer`和`SpringBuilder` - `String::format` and `Stri ...
在日常寫Java的時候,對於字元串的操作是非常普遍的,其中最常見的就是對字元串的組織。也因為這個操作非常普遍,所以誕生了很多方案,總下來大概有這麼幾種:
- 使用
+
拼接 - 使用
StringBuffer
和SpringBuilder
String::format
andString::formatted
- 使用
java.text.MessageFormat
下麵,我們一起來學習一下Java 21中的新方案!如果您對於上面這些還不熟悉的話,建議可以先看一下這篇《Java自帶的4種字元串組織和格式化方法》,瞭解以前的機制,這樣與最新的處理方案做對比,理解會更深刻。
模版表達式
在Java 21中處理字元串的新方法稱為:Template Expressions,即:模版表達式。
模版表達式是Java語言中的一種新表達式。它可以執行字元串插值,幫助開發人員通過編程的方式安全高效地組織字元串。此外,模板表達式不僅僅可以用於組織字元串,它還可以根據特定模型的規則將結構化文本轉換為任何類型的對象。
下麵通過一個簡單的案例來認識一下它:
String blog = "blog.didispace.com";
String str = STR."My blog is \{blog}";
上述代碼中的第2行就是一個模版表達式,其中主要包含三個部分:
- 模版處理器:
STR
- 包含內嵌表達式(
\{blog}
)的模版 - 通過
.
把前面兩部分組合起來,形式上類似方法調用
當模版表達式運行的時候,模版處理器會將模版內容與內嵌表達式的值組合起來,生成結果,所以上面案例中的字元串str在運行時的結果為:My blog is blog.didispace.com
。
多行模版表達式
還記得之前我們的Java新特性專欄中,介紹過Java 15中的文本塊特性嗎?類似下麵這樣的寫法:
String html = """
<html>
<body>
<h1>Java 15 新特性:文本塊 | 程式猿DD</h1>
<p>didispace.com</p>
</body>
</html>
""";
模版表達式也支持類似的多行字元串處理,所以開發者可以用它來方便的組織html、json、xml等字元串內容,比如下麵這樣:
var json = STR."""
{
"user": "\{name}",
"age: \{age}
}
""";
STR模版處理器
上面案例中我們所用的STR模版處理器中的內嵌表達式都採用了字元串內容,而實際上STR模版處理器還有更多的用途。
- 內嵌表達式中還可以之前數學運算,比如:
int x = 10, y = 20;
String s = STR."\{x} + \{y} = \{x + y}";
最終s字元串結果為:10 + 20 = 30
- 內嵌表達式中還可以調用方法,比如:
String s = STR."My blog is \{getMyBlog()}";
假設getMyBlog方法返回的內容為blog.didispace.com
,那麼最終s字元串結果為:My blog is blog.didispace.com
。
- 內嵌表達式中還可以訪問對象的成員變數,比如:
User u = new User("didi", "blog.didispace.com"); // 構造函數參數為name屬性和blog屬性
String s = STR."\{u.name}的博客地地址為:+ \{u.blog}";
最終s字元串結果為:didi的博客地址為:blog.didispace.com
。
FMT模版處理器
除了STR模版處理器之外,Java中還提供了另外一個模版處理器:FMT。FMT模版處理器除了與STR模版處理器一樣提供插值能力之外,還提供了左側的格式化處理。下麵通過例子來直接理解FMT的功能:
record Rectangle(String name, double width, double height) {
double area() {
return width * height;
}
}
Rectangle[] zone = new Rectangle[] {
new Rectangle("Alfa", 17.8, 31.4),
new Rectangle("Bravo", 9.6, 12.4),
new Rectangle("Charlie", 7.1, 11.23),
};
String table = STR."""
Description Width Height Area
\{zone[0].name} \{zone[0].width} \{zone[0].height} \{zone[0].area()}
\{zone[1].name} \{zone[1].width} \{zone[1].height} \{zone[1].area()}
\{zone[2].name} \{zone[2].width} \{zone[2].height} \{zone[2].area()}
Total \{zone[0].area() + zone[1].area() + zone[2].area()}
""";
上面這塊是由STR模版處理器組織字元串表格數據,從模版表達式來看是非常整齊的,但是由於模版中內嵌表達式的值長短不一,最終輸出結果很有可能差強人意,比如STR模版處理器處理後的結果是這樣的:
Description Width Height Area
Alfa 17.8 31.4 558.92
Bravo 9.6 12.4 119.03999999999999
Charlie 7.1 11.23 79.733
Total 757.693
為瞭解決這個問題,就可以採用FMT模版處理器,在每一列左側定義格式
String table = FMT."""
Description Width Height Area
%-12s\{zone[0].name} %7.2f\{zone[0].width} %7.2f\{zone[0].height} %7.2f\{zone[0].area()}
%-12s\{zone[1].name} %7.2f\{zone[1].width} %7.2f\{zone[1].height} %7.2f\{zone[1].area()}
%-12s\{zone[2].name} %7.2f\{zone[2].width} %7.2f\{zone[2].height} %7.2f\{zone[2].area()}
\{" ".repeat(28)} Total %7.2f\{zone[0].area() + zone[1].area() + zone[2].area()}
""";
這樣的結果將是如下這樣,獲得一個整齊的結果:
Description Width Height Area
Alfa 17.80 31.40 558.92
Bravo 9.60 12.40 119.04
Charlie 7.10 11.23 79.73
Total 757.69
關於Java 21中推出的String Templates特性還有很多高級能力,比如:自定義模版處理器等。因為該特性還處於Preview階段,所以DD也還沒有深入研究,僅嘗鮮了一下基本功能,如果您對其他高級能力感興趣,也可以通過官網學習。等該功能正式發佈之後,我會在 Java新特性專欄 中更新解讀所有內容,歡迎關註與收藏。
歡迎關註我的公眾號:程式猿DD。第一時間瞭解前沿行業消息、分享深度技術乾貨、獲取優質學習資源