String Container
Feb 10th, 2020 - Now
字符串拼接
'+' :直接相加,内部实现是创造新的 stringBuilder 然后进行 append 操作然后再 toString() 返回字符串
String a = "abc";
String b = a + "efg";
concat 方法:先将所有的字符放到一个新的 char[] 中,然后再创建新的 String
String a = "abc";
String b = a.concat(",").concat(a);
StringBuilder :容纳可变长的字符串加减变化,扩容通过继续申请连续的空间,直接将接入的字符串拷贝到自己原先维护的内部 char[] 中
StringBuilder a = new StringBuilder("init");
String b = "abc";
a = a.append(b);
StringBuilder c = a.append("end"); // c="initabcend"
StringBuffer :带有 synchronized 的 StringBuffer,其是线程安全的,可以保证多线程中的并发访问
// 查看 StringBuffer 的 append 方法:
public synchronized StringBuffer append(String str) {
toStringCache = null;
super.append(str);
return this;
}
StringUtils.join() :将数组或集合 以某种拼接符拼接到一起,传入的是一个集合和自定的 separator,内部也是使用 StringBuilder 实现
String []list = {"abc", "def", "ghi"};
String a = StringUtils.join(list, "-"); // a="abc-def-ghi"
StringJoiner :JDK8 中的新特性,可以自定义拼接符,前缀和后缀,更重要的是支持流处理,内部也是使用 StringBuilder 实现
// Java Doc 的介绍
// A StringJoiner may be employed to create formatted output
// from a Stream using Collectors.joining(CharSequence)
// 构造函数
StringJoiner(CharSequence delimiter);
StringJoiner(CharSequence delimiter, CharSequence prefix, CharSequence suffix);
// 普通操作
StringJoiner sj = new StringJoiner("COOKIE"); // 注意这里是分隔符不是初始值
sj.add("abc");
sj.add("def");
System.out.println(sj.toString()); // abcCOOKIEdef
StringJoiner sj1 = new StringJoiner("-","begin:",":end");
sj1.add("abc").add("def");
System.out.println(sj1.toString()); // begin:abc-def:end
// 流操作
List<String> list = ImmutableList.of("abc","def","ghi");
list.stream().collect(Collectors.joining("-")); // "abc-def-ghi"
// 上面的 Collectors.joining() 源码
public static Collector<CharSequence, ?, String>
joining(CharSequence delimiter,CharSequence prefix,CharSequence suffix) {
return new CollectorImpl<>(
() -> new StringJoiner(delimiter, prefix, suffix),
StringJoiner::add, StringJoiner::merge,
StringJoiner::toString, CH_NOID);
}
使用的选择:
1. 简单的拼接用 '+' 或者 concat 都可以
2. for 循环的相加用 StringBuilder 或者 StringBuffer(主要是考虑线程安全),严格不用 '+',性能太差 (From Ali Java Manual)
3. 通过一个集合(如: List)进行字符串的拼接,可以考虑使用 StringJoiner 或 StringUtils.join()
4. 如果对一组数据进行拼接或有前缀后缀分隔符的要求,可以考虑转换为Stream,并使用 StringJoiner 处理
Reference
1. Hollis | Java 8中字符串拼接新姿势:StringJoiner
2. Hollis | 为什么阿里巴巴不建议在for循环中使用"+"进行字符串拼接