JDK9之后对String底层存储数据结构进行了重大的修改1,同步也增加了许多新的方法,主要有Text Blocks、chars()、codePoints()、describeConstable()、formatted()、indent()、isBlank()、isEmpty()、lines()、repeat()、strip()、stripLeading()、stripIndent()、stripTrailing()、translateEscapes(),接下来就逐一看看每个方法怎么用。
Text Blocks
在JDK8之前我们想定义一个JSON String必须要各种转义、拼接,可读性非常差,看起来也比较乱,JDK17里我们可以使用"""来定义一个text block,看起来清爽多了
//JDK8之前想要定义一个JSON数据格式
String json = "{\n" +
" \"name\": \"admin\",\n" +
" \"id\": 1\n" +
"}";
String json2 = """
{
"name": "admin",
"id": 1
}""";
//JDK17+
System.out.println(json);
System.out.println(json2);
//true
System.out.println(json.equals(json2));
使用Text Blocks需要注意以下几点:
- Text Blocks就是个语法糖,编译后还是和之前一样
- 前后"““必须放在两行,不能放同一行代码中,第一行的””"后面不能放字符串,不然会报Illegal text block start: missing new line after opening quotes
chars()
String name = "12345工😃";
//JDK9+ 获取String中所有char字符,一个emoji会获取到多个char
IntStream chars = name.chars();
chars.forEach(x -> System.out.println(Character.toChars(x)));
//输出
1
2
3
4
5
工
?
?
codePoints()
String name = "12345工😃";
//JDK9+ 获取String中所有char emoji会拆一个
IntStream chars = name.codePoints();
chars.forEach(x -> System.out.println(Character.toChars(x)));
//输出
1
2
3
4
5
工
😃
chars()和codePoints()都是获取String中的char,主要区别是codePoints()获取char支持的编码更多了,如果是emoji chars()会得到两个char,codePoints()只会获取一个,想要了解具体的char编码可以参考《其实你并不懂 Unicode》2;
describeConstable()、resolveConstantDesc()
String name = "12345工😃";
//JDK12+
Optional<String> optionalString = name.describeConstable();
System.out.println(optionalString.get());
public Optional<String> describeConstable() {
return Optional.of(this);
}
这个方法比较简单,就是返回一个Optional对象,加入这个方法的主要原因是String实现了Constable和ConstantDesc两个接口,实现这两个接口的目的是JAVA
引入了新的API以对关键类文件和运行时工件的名义描述进行建模,尤其是可以从常量池中加载的常量3。
public final class String
implements java.io.Serializable, Comparable<String>, CharSequence,
Constable, ConstantDesc {
}
public interface Constable {
Optional<? extends ConstantDesc> describeConstable();
}
public sealed interface ConstantDesc
permits ClassDesc,
MethodHandleDesc,
MethodTypeDesc,
Double,
DynamicConstantDesc,
Float,
Integer,
Long,
String {
Object resolveConstantDesc(MethodHandles.Lookup lookup) throws ReflectiveOperationException;
}
formatted()
String name = "12345工😃%s-%d";
//JDK15+
String formattedString = name.formatted("admin",1);
Assertions.assertEquals(String.format(name,"admin",1),formattedString);
formatted()方法等同步于String.format()
indent()
String name = "1\n2\n3\r4";
//JDK11 按行缩进
String indentString = name.indent(20);
System.out.println("|" + indentString + "|");
//输出
| 1
2
3
4
|
indent()可以缩进字符串,并且可以按\n、\r、\r\n拆分后将每一行都缩进指定空格
isBlank()、isEmpty()
//true
System.out.println("".isBlank());
//true
System.out.println("".isEmpty());
//true
System.out.println(" ".isBlank());
//false
System.out.println(" ".isEmpty());
//true
System.out.println("\t\n".isBlank());
//false
System.out.println("\n\n".isEmpty());
这两个方法可以方便我们判断字符串是否为空了
lines()
String name = "1\n2\r3\r\n4";
//JDK11+ 按\n\r拆分String
List<String> lines = name.lines().collect(Collectors.toList());
lines.forEach(System.out::println);
//输出
1
2
3
4
lines()方法可以快速的帮我们将String 按\n、\r、\r\n拆分成一行一行
repeat()
String name = "Admin";
//JDK11+ 重复String
String jdkRepeatString = name.repeat(3);
/AdminAdminAdmin
System.out.println(jdkRepeatString);
repeat()将字符串重复拼接n次
strip()
String name = "\u0020 \t admin\0";
//JDK11+
System.out.println(name.strip() + "|");
System.out.println(name.trim() + "|");
//输出
admin |
admin|
strip()和trim()有点类似,不同的是trim()仅删除字符 <= U+0020(空格);strip()删除所有 Unicode 空白字符(但不是所有控制字符,例如 \0)
stripLeading()、stripIndent()、stripTrailing()
String name = " admin \n admin ";
//JDK11+
System.out.println("|"+name.stripLeading()+"|");
System.out.println("-------------");
System.out.println("|"+name.stripIndent()+"|");
System.out.println("-------------");
System.out.println("|"+name.stripTrailing()+"|");
//输出
|admin
admin |
-------------
|admin
admin|
-------------
| admin
admin|
stripLeading()去除前面的空格,stripIndent()可以按\n、\r、\r\n拆分后按行去除前后空格,stripTrailing()去除后面空格
translateEscapes()
String name = "\b\r\t\f";
//JDK15+
String transform = name.translateEscapes();
System.out.println(transform);
将\b\t\n\f等字面字符转义
JDK17新特性之–新的Compact Strings(JEP 254) - 掘金 (juejin.cn) ↩︎
其实你并不懂 Unicode - 知乎 ↩︎
JEP 334: JVM Constants API ↩︎