都知道StringBuilder、StringBuffer,可知StringJoiner?
今早看String源码的时候发现 join()方法中有StringJoiner,出于好奇把该文件从头到尾看了一遍,现介绍下StringJoiner。
一、应用环境
从源码来看该文件适用环境 JDK8 ,如图:
二、属性及方法
1. 属性
1.1 prefix
字符串拼接的前缀,私有并且是 一旦赋值不可更改的String类型变量。
1.2 suffix
字符串拼接后缀,私有并且一旦赋值不可更改的String类型变量。
1.3 delimiter
字符串拼接时,内容之间的分隔符,私有并且一旦赋值不可更改的String类型变量。
1.4 value
私有的StringBuilder实例。StringBuilder—在任何时候,由前缀构造的字符,添加的元素由分隔符分隔,但没有后缀,因此我们可以更容易地添加元素,而不必每次都修改后缀。
1.5 emptyValue
私有String类型变量。默认情况下,toString()返回的由前缀+后缀组成的字符串,或值的属性,当没有添加元素时,即当它为空时。这可能会被用户覆盖为包括空字符串在内的其他值。
2.方法
2.1 构造方法
该类中没有无参构造,仅有有参构造,分别是单个参数构造和三个参数构造。
2.1.1 单参构造
如下图所知,单参构造方法仅传 delimiter(分隔符) 即可,在其方法体中调用的是多参构造方法,并且 prefix和suffix 都设置为空字符。
(注:这里的空字符和null是有区别的,在多参构造方法中会捕捉null并抛出异常。)
2.1.2 多参构造
该类中多参构造指的仅仅是含有三个参数的构造方法,如下图所示。
该构造方法在构建StringJoiner对象时可以设置 delimiter、prefix、suffix 变量,但是绝对不能传 null
,否则会抛出对应的 NullPointerException
,如下图所示:
// 示例1 delimiter设置 null
StringJoiner sj = new StringJoiner(null,"sjpre","sjsuf");
// 示例2 prefix 设置 null
StringJoiner sj = new StringJoiner(",",null,"sjsuf");
// 示例3 suffix 设置 null
StringJoiner sj1 = new StringJoiner(",","sjpre",null);
2.2 setEmptyValue
使用StringJioner时,并且还有没有添加元素时(当它为空时)要使用的 emptyValue 参数副本。注意,一旦调用了add方法,即使添加的元素与空的 String 对应,StringJoiner也不再认为是空的。如果调用时传 null
会抛出 NullPointerException
异常。
// 示例 调用setEmptyValue方法时传入null
StringJoiner sj1 = new StringJoiner(",","sjpre","sjsuf");
sj1.setEmptyValue(null);
2.3 toString
该方法是重写Object的toString方法。返回由 prefix 、delimiter、suffix 组成的当前值,如果没有添加任何元素,则将返回 prefix + suffix 或 emptyValue 字符串。
2.3.1 返回 prefix 、delimiter、suffix 组成的字符串
// 示例 构建含有prefix、suffix、delimiter 的StringJoiner实例
StringJoiner sj1 = new StringJoiner(",","sjpre_","_sjsuf");
// 使用链式结构添加数据,验证分隔符是否有效
sj1.add("使用StringJoiner").add("探究StringJoiner神秘之处");
// 输出 实例sj1的内容
System.out.println(sj1.toString());
2.3.2 返回 prefix + suffix 组成的字符串
// 示例 当实例sj1不添加任何数据,输出时仅包含prefix+suffix
StringJoiner sj1 = new StringJoiner(",","sjpre_","_sjsuf");
System.out.println(sj1.toString());
注意:
该示例返回的结果看似是prefix+suffix的值,实则是 emptyValue 的值。因为在多参构造方法里 执行了 this.emptyValue = this.prefix + this.suffix;
代码,最终将prefix+suffix的值赋给emptyValue 变量。并且根据StringJoiner.toString
源码可知,如果 value
实例为null
返回emptyValue 。此处没有单独设置 emptyValue ,所以直观感觉输出了prefix+suffix。
2.3.3 单独设置emptyValue ,并返回 emptyValue
// 单独设置 setEmptyValue 的值,弥补上面示例缺陷
StringJoiner sj1 = new StringJoiner(",","sjpre_","_sjsuf");
sj1.setEmptyValue("没有添加任何值,这里是setemptyValue方法");
System.out.println(sj1.toString());
为什么出现这样的结果?直接上源码消除你的疑问。
通过分析源码可以明白以上示例结果出现的原由。
2.4 prepareBuilder
该方法是 StringJoiner 私用方法,在内部 add()
和 merge()
方法逻辑中调用。当 StringBuilder 实例不为空时添加 delimiter(分隔符);为空时创建StringBuilder实例,然后添加 prefix 前缀,最后返回StringBuilder实例。
2.5 add
添加内容,调用的是 StringBuilder 的append()方法,并返回添加后的StringJoiner实例,可以使用链式结构添加数据。
StringJoiner sj1 = new StringJoiner(",","sjpre_","_sjsuf");
sj1.add("添").add("加").add("内").add("容"); // 链式添加结构
System.out.println(sj1.toString());
2.6 merge
将两个StringJoiner合并为一个StringJoiner实例,调用该方法时需要传输StringJoiner实例。如下图源码所示。
仅会合并传入的StringJoiner 实例的vlaue
值,无论传入的StringJoiner实例是否含有 prefix和suffix,都不会合并。会保留调用merge方法
实例的 prefix和suffix。还需要注意的是传入的StringJoiner实例不能为 null
,否则会抛出 NullPointerException
异常。
// 创建第一个StringJoiner实例sjOne
StringJoiner sjOne = new StringJoiner(",","sjpreOne_","_sjsufOne");
// sjOne添加内容
sjOne.add("测").add("试").add("StringJoinerOne");
// 创建第一个StringJoiner实例sjTwo
StringJoiner sjTwo = new StringJoiner("+","sjpreTwo_","_sjsufTwo");
// sjTwo添加内容
sjTwo.add(" DEMO").add("demo").add("StringJoinersTwo ");
// sjOne调用merge方法与sjTwo实例合并,输出合并后的结果
System.out.println(sjOne.merge(sjTwo).toString());
以上实例中,sjOne和sjTwo实例都含有 prefix、suffix、delimiter,sjOne调用merge方法与sjTwo合并,通过输出结果可以看出sjTwo实例的prefix和suffix没有合并,合并的只有sjTwo内部的StringBuilder实例value。
当传入null
时,会抛出NullPointerException
异常。
// 示例 调用merge传入null
StringJoiner sjOne = new StringJoiner(",","sjpreOne_","_sjsufOne");
sjOne.merge(null);
2.7 length
返回StringJoiner的长度。如果没有调用任何添加方法,将返回 prefix+suffix 长度或者 emptyValue 的长度。
三、总结
- 该类适用在 JDK8+ 的环境上。
- 避免拼接字符串时,生硬处理分隔符的问题。注:分隔符 不可以传
null
。 - 合理的设置字符串前后缀,但不可以传
null
。 - 合并多个StringJoiner实例,合并时不能合并
null
。 - StringJoiner实例没有添加任何内容时,会输出
emptyValue
的值。 - StringJoiner底层使用的是StringBuilder,非线程安全。不适用并发场景,否则会出现ABA问题。
本文地址:https://blog.csdn.net/qq_38922576/article/details/109800830