引言
StringJoiner是java.util包下的一个类,在String.join()方法方法以及java.util.stream类的一些方法中会被用到,总体来说,这个类是比较简单的,我们来分析一下这个类的实现。
用途描述
先看源码中的注释来理解一下这个类的用途:
/*** {@code StringJoiner} is used to construct a sequence of characters separated* by a delimiter and optionally starting with a supplied prefix* and ending with a supplied suffix.* <p>* Prior to adding something to the {@code StringJoiner}, its* {@code sj.toString()} method will, by default, return {@code prefix + suffix}.* However, if the {@code setEmptyValue} method is called, the {@code emptyValue}* supplied will be returned instead. This can be used, for example, when* creating a string using set notation to indicate an empty set, i.e.* <code>"{}"</code>, where the {@code prefix} is <code>"{"</code>, the* {@code suffix} is <code>"}"</code> and nothing has been added to the* {@code StringJoiner}.
StringJoiner用来构造一个字符数组,这个数组被一个分隔符delimiter分隔,并且有一个可选的前缀prefix和一个可选的后缀suffix。在向StringJoiner增加一些东西之前,它的toString方法,会默认返回前缀+后缀即prefix+suffix,如果setEmptyValue方法被调用,toString方法会返回emptyValue。当使用字符串表示一个空的集合时,例如{},时可以被用到。
成员变量和构造方法
private final String prefix;private final String delimiter;private final String suffix;private StringBuilder value;private String emptyValue;
前缀prefix、分隔符delimiter和后缀suffix肯定都得有,然后可以通过emptyValue指定默认的值。value是一个StringBuilder,用这个StringBuilder来进行字符串的拼接。
再看构造方法:
public StringJoiner(CharSequence delimiter) {this(delimiter, "", "");}public StringJoiner(CharSequence delimiter,CharSequence prefix,CharSequence suffix) {Objects.requireNonNull(prefix, "The prefix must not be null");Objects.requireNonNull(delimiter, "The delimiter must not be null");Objects.requireNonNull(suffix, "The suffix must not be null");// make defensive copies of argumentsthis.prefix = prefix.toString();this.delimiter = delimiter.toString();this.suffix = suffix.toString();this.emptyValue = this.prefix + this.suffix;}
两个构造方法,前者调用的是后者,后者分别设置前缀prefix、后缀suffix和分隔符delimiter,同时会设置emptyValue为prefix+suffix,也就是说emptyValue默认是prefix+suffix。你也可以调用下面的方法来设置emptyValue的值:
public StringJoiner setEmptyValue(CharSequence emptyValue) {this.emptyValue = Objects.requireNonNull(emptyValue,"The empty value must not be null").toString();return this;}
字符串的拼接
add方法用来实现字符串的拼接:
private StringBuilder prepareBuilder() {if (value != null) {value.append(delimiter);} else {value = new StringBuilder().append(prefix);}return value;}
add方法实际上是调用了StringBuilder的append方法来实现字符串的拼接,prepareBuilder方法如下:
private StringBuilder prepareBuilder() {if (value != null) {value.append(delimiter);} else {value = new StringBuilder().append(prefix);}return value;}
逻辑也很简单,如果value也就是StringBuilder为null,就会创建一个新的StringBuilder并默认将prefix添加进去,否则,就调用StringBuilder的append方法将分隔符添加进去,所以StringBuilder中是没有suffix的,这样是为了每次执行add方法不用去管suffix。
toString方法
@Overridepublic String toString() {if (value == null) {return emptyValue;} else {if (suffix.equals("")) {return value.toString();} else {int initialLength = value.length();String result = value.append(suffix).toString();// reset value to pre-append initialLengthvalue.setLength(initialLength);return result;}}}
如果value也就是StringBuilder为空,也就是还没有添加任何东西,就返回emptyValue,否则判断suffix是否为空字符串,如果是空字符串,直接返回StringBuilder.toString(),因为StringBuilder中没有suffix,所以这样返回没有问题,如果suffix不是空字符串,就需要将suffix添加到StringBuilder然后返回StringBuilder.toString()。
