引言
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 arguments
this.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方法
@Override
public 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 initialLength
value.setLength(initialLength);
return result;
}
}
}
如果value也就是StringBuilder为空,也就是还没有添加任何东西,就返回emptyValue,否则判断suffix是否为空字符串,如果是空字符串,直接返回StringBuilder.toString(),因为StringBuilder中没有suffix,所以这样返回没有问题,如果suffix不是空字符串,就需要将suffix添加到StringBuilder然后返回StringBuilder.toString()。