Fellow Travellers

Java 8 之StringJoiner的使用

万世威
字数统计: 888阅读时长: 4 min
2018/10/24 Share

Java8–StringJoiner的使用

示例一

1
2
3
4
5
6
7
8
9
10
public class StringJoinerTest1 {
public static void main(String[] args) {
StringJoiner joiner = new StringJoiner("--", "[[[_ ", "_]]]");
System.out.println(joiner.toString());
System.out.println(joiner.length());
}
}
// result
[[[_ _]]]
9

API介绍

StringJoiner 是 java8 新增的类。

构造器:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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(CharSequence delimiter) {
this(delimiter, "", "");
}

delimiter 是分隔符 , prefix 是前缀 , suffix 是 后缀.

emptyValue 是本类的空值.

add

1
2
3
4
StringJoiner joiner = new StringJoiner("--", "[[[_", "_]]]");
joiner.add("1");
System.out.println("toString: " + joiner.toString());
System.out.println("length: " + joiner.length());

分析源码:

1
2
3
4
public StringJoiner add(CharSequence newElement) {
prepareBuilder().append(newElement);
return this;
}
1
2
3
4
5
6
7
8
private StringBuilder prepareBuilder() {
if (value != null) {
value.append(delimiter);
} else {
value = new StringBuilder().append(prefix);
}
return value;
}
1
2
3
4
5
6
7
public AbstractStringBuilder append(CharSequence s) {
if (s == null) return appendNull();
if (s instanceof String) return this.append((String)s);
if (s instanceof AbstractStringBuilder)
return this.append((AbstractStringBuilder)s);
return this.append(s, 0, s.length());
}

​ 发现StringJoiner底层依旧使用的 StringBuilder,第一次添加数据时,会生成StringBuilder对象,并添加 “前缀”,后续添加字符时,追加 “分隔符”,最后调用 append 方法,最底层调用 System.arraycopy 方法。

1
public static void arraycopy(Object src,int srcPos,Object dest,int destPos,int length)

src:源数组

srcPos:源数组要复制的起始位置

dest:目的数组

destPos:目的数组放置的起始位置

length:复制的长度

注意:src and dest都必须是同类型或者可以进行转换类型的数组.

toString

1
2
3
4
5
6
7
8
9
10
11
12
13
14
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();
value.setLength(initialLength);
return result;
}
}
}

value == null, 返回 空。

不为空,判断 是否需要添加 后缀

length

1
2
3
4
5
6
7
8
public int length() {
// Remember that we never actually append the suffix unless we return
// the full (present) value or some sub-string or length of it, so that
// we can add on more if we need to.
return (value != null ? value.length() + suffix.length() :
emptyValue.length());
}
}

value 不为 null ,返回 value的长度 + 后缀长度(不为null时,已经计算了value+前缀)

merge

1
2
3
4
5
6
7
8
StringJoiner joiner = new StringJoiner("--", "[[[_", "_]]]");
joiner.add("1").add("2").add("3").add("4");

StringJoiner joiner2 = new StringJoiner("...");
joiner2.add("a").add("b").add("c");

joiner.merge(joiner2);
System.out.println(joiner.toString());

分析:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public StringJoiner merge(StringJoiner other) {
Objects.requireNonNull(other);
if (other.value != null) {
final int length = other.value.length();
// lock the length so that we can seize the data to be appended
// before initiate copying to avoid interference, especially when
// merge 'this'
StringBuilder builder = prepareBuilder();
builder.append(other.value, other.prefix.length(), length);
}
return this;
}
// result
[[[_1--2--3--4--a...b...c_]]]

实例二

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
import java.util.StringJoiner;

/**
* @author wsw
*/
public class StringJoinerTest {

public static void main(String args[]) {

StringJoiner joiner = new StringJoiner("--", "[[[_", "_]]]");
System.out.println("toString: " + joiner.toString());
System.out.println("length: " + joiner.length());

System.out.println("******************(1)********************");

joiner.add("1");
joiner.add("2");
joiner.add("3");
joiner.add("4");
System.out.println("toString: " + joiner.toString());
System.out.println("length: " + joiner.length());

System.out.println("******************(2)********************");

StringJoiner joiner2 = new StringJoiner("...");
System.out.println("toString: " + joiner2.toString());
System.out.println("length: " + joiner2.length());

System.out.println("******************(3)********************");

joiner2.add("a");
joiner2.add("b");
joiner2.add("c");
System.out.println("toString: " + joiner2.toString());
System.out.println("length: " + joiner2.length());

System.out.println("******************(4)********************");

joiner.merge(joiner2);
System.out.println("toString: " + joiner.toString());

System.out.println("******************(5)********************");

StringJoiner joiner3 = new StringJoiner("==", "qianzhui", "houzhui");
joiner3.add("壹");
joiner3.add("贰");
joiner3.add("叁");

joiner.merge(joiner3);
System.out.println("toString: " + joiner.toString());
System.out.println("length: " + joiner.length());

System.out.println("******************(6)********************");
joiner.merge(joiner); // joiner.merge(this)
System.out.println("toString: " + joiner.toString());
System.out.println("length: " + joiner.length());

}
}
// result
toString: [[[__]]]
length: 8
******************(1)********************
toString: [[[_1--2--3--4_]]]
length: 18
******************(2)********************
toString:
length: 0
******************(3)********************
toString: a...b...c
length: 9
******************(4)********************
toString: [[[_1--2--3--4--a...b...c_]]]
******************(5)********************
toString: [[[_1--2--3--4--a...b...c--壹==贰==叁_]]]
length: 38
******************(6)********************
toString: [[[_1--2--3--4--a...b...c--壹==贰==叁--1--2--3--4--a...b...c--壹==贰==叁_]]]
length: 70
CATALOG
  1. 1. Java8–StringJoiner的使用
    1. 1.1. 示例一
    2. 1.2. API介绍
    3. 1.3. 实例二