前言
最近出于习惯问题,顺手点开了String的源码,意外发现String在JDK 8中新增了join方法。(实在惭愧,JDK 8都发布多久了。。。)
源码
String重载了join方法,两个方法的异同点在于,第一个方法使用的可变参数,第二个方法使用的可迭代参数,这样设计主要是为了方法适用性更广。比如参数可以传一个数组、集合等等。下面就拿一个方法的源码来解析
String 类
/**
* delimiter 分隔符
* elements 需要连接的字符数组
*/
public static String join(CharSequence delimiter, CharSequence... elements) {
// 空指针判断
Objects.requireNonNull(delimiter);
Objects.requireNonNull(elements);
// Number of elements not likely worth Arrays.stream overhead.
// 此处用到了StringJoiner(JDK 8引入的类)
// 先构造一个以参数delimiter为分隔符的StringJoiner对象
StringJoiner joiner = new StringJoiner(delimiter);
for (CharSequence cs: elements) {
// 拼接字符
joiner.add(cs);
}
return joiner.toString();
}
查看StringJoiner源码
// 前缀
private final String prefix;
// 分隔符
private final String delimiter;
// 后缀
private final String suffix;
// 值
private StringBuilder value;
/**
* 构造器
*/
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;
}
// 拼接
public StringJoiner add(CharSequence newElement) {
prepareBuilder().append(newElement);
return this;
}
// 预拼接value
private StringBuilder prepareBuilder() {
// value已加前缀
if (value != null) {
// 此时添加分隔符
value.append(delimiter);
} else {
// value未加前缀时需要先添加前缀
value = new StringBuilder().append(prefix);
}
return value;
}
//重写了toString 方法
@Override
public String toString() {
if (value == null) {
// value未进行任何字符拼接时反悔emptyValue
return emptyValue;
} else {
// 后缀为""字符时,直接返回value
if (suffix.equals("")) {
return value.toString();
} else {
// 获取value未拼接后缀的长度
int initialLength = value.length();
String result = value.append(suffix).toString();
// reset value to pre-append initialLength
// 此处是为了保证value.toString()为未拼接后缀前的字符串
value.setLength(initialLength);
return result;
}
}
}
使用方式
String delimiter = "-";
String[] elements = {"JDK", "8", "String", "join"};
List<String> list = new ArrayList<String>(Arrays.asList(elements));
System.out.println(String.join(delimiter, elements));
System.out.println(String.join(delimiter, "JDK", "8", "String", "join"));
System.out.println(String.join(delimiter, list));
输出结果