# 超级好用的 StringJoiner
主要先说一下自己的最近的需求,类似于
1 | //<402162465.20106.1625035747695.JavaMail.saicapp@deployment-invoiceservice-7bc58468c5-gtqb7> |
需要做的有两步,将 <
>
去掉,然后再加前后缀 <
, >
基本上的做法就是:
1 | public static String messageIdHandle(String messageId) { |
所以我觉得 StringJoiner
挺好玩的!
# StringJoiner
类详解
我们可以构造由定界符分隔的字符序列,并可选地以提供的前缀开头并以提供的后缀结尾。然后调用 add
方法添加字符串。例子代码如下:
1 | StringJoiner stringJoiner = new StringJoiner(":", "[", "]"); |
打印结果:
# 参数
StringJoiner 总共有五个参数:
1 | private final String prefix; //前缀 |
1 | private StringBuilder value; |
1 | /* |
# 构造器
参数比较多的构造器
1 | public StringJoiner(CharSequence delimiter,CharSequence prefix,CharSequence suffix) |
这里面三个参数分别是前缀后缀和连接符,然后这里有一个操作就是将 emptyValue
赋值了前缀 + 后缀的字符串。也就是说当你用了这个构造器的时候, emptyValue
就已经有值了,就是前缀 + 后缀拼接。当你 StringJoiner
不执行 add
方法直接 toString()
时,会 return
的对象就是你的前缀 + 后缀。例子:
参数比较少的构造器:
1 | public StringJoiner(CharSequence delimiter) { |
其实还是调用的三参构造器,只不过前后缀默认值为 ""
, 也就是没有前后缀。这种情况下 emptyValue
是什么呢? 其实和上面一样的, ""+""
就是 ""
, 不难理解。
# 方法
先看上面提到最多的 toString().
1 |
|
当 value
为空 (也就是 StringBuilder
为空) 时,会 return emptyVaule
, 如果不为空,就会加上一个给你加后缀的操作。当然这里加后缀你可以看作一次性的,他在加之前会取一个长度,不管你后缀多长,加完之后会 set
到初始长度。
知道了后缀是这里加的,那前缀呢。
来看最核心的 add
方法:
1 | public StringJoiner add(CharSequence newElement) { |
前缀就是在你调用第一个 add 的时候就加上了,为什么是第一个呢,因为第一次调用 add
的时候,你的 value
肯定是空的,所以它会走 else
的逻辑给你构造一个 StringBuilder
出来,这个时候会把前缀加好。所以你后面不管有几个 add
,都是基于一个 StringBuilder
上在加字符串。当你的 value
不为空了,就会给你拼接上连接符,最后再拼接上 add()
方法里的参数。完美。
再结合 toString
方法来看,当你没有调用过 add
方法而直接 toString
时, value
为空,它就会 return emptyValue
了。
再来看个和 emptyValue
有关的方法 setEmptyValue(CharSequence emptyValue):
1 | public StringJoiner setEmptyValue(CharSequence emptyValue) { |
这个方法其实是暴露给开发者主动设置 emptyValue
值的方法,也就是说,当你没有调用 set
方法, emptyValue
默认值为前缀 + 后缀,不管前后缀是否为空;当你调用了 set
方法, emptyValue
就是设置的值。 举个例子:
这里的打印结果就是 anson
,注意不是 [anson]
哦。
还有一个有关字符串操作的方法 merge(StringJoiner)
1 | public StringJoiner merge(StringJoiner other) { |
这里面调用了一个 StringBuilder
的 append()
重载方法:
1 | public StringBuilder append(CharSequence s, int start, int end) { |
也就是说 merge
操作是把另一个 StringJoiner(简称sj2)
的从前缀开始 (不包括前缀) 包括连接符但是不包括后缀的字符串加进去 sj1
里面。
上个例子:
前后缀都是 sj1
的, ac
间的连接符是 sj2
的。
最后再看个简单的方法收尾
1 | public int length() { |
length()
方法大家最熟悉,获取长度。这里能看到有一个好处就是当你没有调用 add
方法也就是没有初始化 StringBuilder
时,调用这个方法不会空指针,因为有默认的 emptyValue。
# 总结
总结一下, Java 8
的新类 StringJoiner
用法很简单,其实就是一个披着 StringJoiner
皮的 StringBuilder
而已嘛。不过有人帮你封装好了加减后缀和连接符的方法也是好的!