StringJoiner
/**
* StringJoiner 使用指定的分割符將多個字符串進行拼接,並可指定前綴和後綴
*
* @see java.util.stream.Collectors#joining(CharSequence)
* @see java.util.stream.Collectors#joining(CharSequence, CharSequence, CharSequence)
* @since 1.8
*/
public final class StringJoiner {
/**
* 前綴
*/
private final String prefix;
/**
* 分割符
*/
private final String delimiter;
/**
* 後綴
*/
private final String suffix;
/** 持續添加的字符串數組 */
private String[] elts;
/** 已添加的字符串個數 */
private int size;
/** 所有字符串的總長度,包括前綴和後綴 */
private int len;
/**
* 空值
*
* When null, prefix + suffix is used as the empty value.
*/
private String emptyValue;
/**
* 創建分割符爲 delimiter,前綴和後綴都爲 "" 的 StringJoiner 對象
*
* @param delimiter 分割符
*/
public StringJoiner(CharSequence delimiter) {
this(delimiter, "", "");
}
/**
* 創建指定分割符、前綴、後綴的 StringJoiner
*
* @param delimiter 用於連接字符串的分隔符
* @param prefix 前綴字符序列
* @param suffix 後綴字符序列
*/
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();
}
/**
* 追加字符串 newElement 到此 StringJoiner 中
*
* @param newElement 追加的新元素
*/
public StringJoiner add(CharSequence newElement) {
final String elt = String.valueOf(newElement);
// 1)創建長度爲 8 的初始緩衝區
if (elts == null) {
elts = new String[8];
} else {
// 如果已滿,則執行雙倍擴容
if (size == elts.length) {
elts = Arrays.copyOf(elts, 2 * size);
}
// 記錄總字符數
len += delimiter.length();
}
// 記錄總字符數
len += elt.length();
// 寫入目標元素
elts[size++] = elt;
return this;
}
/**
* 返回此 StringJoiner 的字符串表示
*/
@Override
public String toString() {
final String[] elts = this.elts;
// 1)嘗試返回空值
if (elts == null && emptyValue != null) {
return emptyValue;
}
final int size = this.size;
final int addLen = prefix.length() + suffix.length();
// 如果未指定前綴和後綴
if (addLen == 0) {
// 完成字符串拼接
compactElts();
return size == 0 ? "" : elts[0];
}
final String delimiter = this.delimiter;
final char[] chars = new char[len + addLen];
int k = getChars(prefix, chars, 0);
if (size > 0) {
k += getChars(elts[0], chars, k);
for (int i = 1; i < size; i++) {
k += getChars(delimiter, chars, k);
k += getChars(elts[i], chars, k);
}
}
k += getChars(suffix, chars, k);
return new String(chars);
}
private void compactElts() {
// 完成字符串拼接
if (size > 1) {
final char[] chars = new char[len];
// 寫入第一個字符串
int i = 1, k = getChars(elts[0], chars, 0);
do {
// 寫入分割符
k += getChars(delimiter, chars, k);
// 寫入後一個字符串
k += getChars(elts[i], chars, k);
elts[i] = null;
} while (++i < size);
size = 1;
elts[0] = new String(chars);
}
}