当前位置:网站首页>StringJoiner详解
StringJoiner详解
2022-07-31 02:13:00 【likelong965】
一、什么是StringJoiner
StringJoiner是Java 8新增的一个API,他是基于StringBuilder实现,用于实现对字符串之间通过分隔符拼接的场景。
有些字符串拼接场景,使用StringBuilder或StringBuffer会显得比较繁琐。
如以下字符串:
(hello, guys, 欢迎大家)
这种字符串有前缀后缀并且由 “,” 分隔的字符串,在 Java 8 之前要使用 StringBuilder/ StringBuffer 进行拼接,如下:
StringBuilder sb = new StringBuilder();
sb.append("(");
sb.append("hello");
sb.append(",");
sb.append("guys");
sb.append(",");
sb.append("欢迎大家");
sb.append(")");
String str = sb.toString();
上述代码显得十分难看又略显繁琐。
二、StringJoiner基本使用
(hello, guys, 欢迎大家)
Java 8使用StringJonier来实现,如下:
StringJoiner stringJoiner = new StringJoiner(",", "(", ")");
stringJoiner.add("hello");
stringJoiner.add("guys");
stringJoiner.add("欢迎大家");
StringJonier实现就显得比较优雅!
三、StringJoiner详细介绍
StringJoiner 的类结构图:

3.1、成员变量
- prefix:拼接后的字符串前缀
- delimiter:拼接时的字符串分隔符
- suffix:拼接后的字符串后缀
- value:拼接后的值
- emptyValue:空值的情况,
value为 null 时返回
3.2、构造方法
StringJoiner有两个构造方法
一个是要求传入分隔符、前缀和后缀
另一个是只需要传入分隔符(前缀和后缀默认是"")
源码如下:
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;
}
可以看到 emptyValue 默认为前缀+后缀组成。
3.3、公开方法
- setEmptyValue:设置空值
- toString:转换成 String
- add:添加字符串
- merge:从另一个 StringJoiner 合并
- length:长度(包括前缀后缀)
主要看add()源码:
public StringJoiner add(CharSequence newElement) {
prepareBuilder().append(newElement);
return this;
}
private StringBuilder prepareBuilder() {
if (value != null) {
value.append(delimiter);
} else {
value = new StringBuilder().append(prefix);
}
return value;
}
toString()源码
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;
}
}
}
可以看到内部其实就是用的StringBuilder进行封装的,首次创建会先拼接前缀,后续先添加分隔符,再添加字符串。
主要就通过上述两个方法,实现前缀、后缀以及分隔符的拼接。(最后输出才进行后缀的拼接)
另外一点,add 方法就是返回 StringJoiner 本身,所以可以像StringBuilder/ StringBuffer 一样进行流式处理。如下:
StringJoiner stringJoiner = new StringJoiner(",", "(", ")").add("hello").add("guys").add("欢迎大家");
System.out.println(stringJoiner);
3.4、空值处理
没有拼接任何字符串的几个空值处理场景。
3.4.1、输出空白字符串
StringJoiner stringJoiner = new StringJoiner(",");
System.out.println(stringJoiner.toString());
3.4.2、输出前后缀
StringJoiner stringJoiner = new StringJoiner(",", "[", "]");
System.out.println(stringJoiner.toString());
输出:[]
3.4.3、输出指定字符串
StringJoiner stringJoiner = new StringJoiner(",", "[", "]");
stringJoiner.setEmptyValue("likelong");
System.out.println(stringJoiner.toString());
输出:likelong
上面三个小案例都可以在源码中找到答案。
四、String.join()
String.join() 这是针对 StringJoiner 又封装了一层的 API,同样出自 Java 8,可以传入动态参数或者迭代器。
- java.lang.String#join(java.lang.CharSequence, java.lang.CharSequence…)
- java.lang.String#join(java.lang.CharSequence, java.lang.Iterable<? extends java.lang.CharSequence>)
源码:
public static String join(CharSequence delimiter, CharSequence... elements) {
Objects.requireNonNull(delimiter);
Objects.requireNonNull(elements);
// Number of elements not likely worth Arrays.stream overhead.
StringJoiner joiner = new StringJoiner(delimiter);
for (CharSequence cs: elements) {
joiner.add(cs);
}
return joiner.toString();
}
public static String join(CharSequence delimiter,
Iterable<? extends CharSequence> elements) {
Objects.requireNonNull(delimiter);
Objects.requireNonNull(elements);
StringJoiner joiner = new StringJoiner(delimiter);
for (CharSequence cs: elements) {
joiner.add(cs);
}
return joiner.toString();
}
由源码可以看出,该方法只能进行分隔符拼接,并不能拼接前缀和后缀。
实际操作:
String join = String.join(",", "hello", "world", "likelong");
System.out.println(join);
输出:hello,world,likelong
五、Collectors.joining(“,”)
Collectors.joining(“,”)底层也是通过StringJoiner实现的。源码如下:
public static Collector<CharSequence, ?, String> joining(CharSequence delimiter) {
return joining(delimiter, "", "");
}
/** * Returns a {@code Collector} that concatenates the input elements, * separated by the specified delimiter, with the specified prefix and * suffix, in encounter order. * * @param delimiter the delimiter to be used between each element * @param prefix the sequence of characters to be used at the beginning * of the joined result * @param suffix the sequence of characters to be used at the end * of the joined result * @return A {@code Collector} which concatenates CharSequence elements, * separated by the specified delimiter, in encounter order */
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);
}
针对不同的场景使用不同的 API,这才是最佳最优雅的处理方式,不要只会使用 StringBuilder!
边栏推荐
- VSCode Plugin: Nested Comments
- leetcode-128: longest continuous sequence
- Maximum monthly salary of 20K?The average salary is nearly 10,000... What is the experience of working in a Huawei subsidiary?
- 拒绝加班,程序员开发的效率工具集
- Linux下redis7的安装,启动与停止
- 【Bank Series Phase 1】People's Bank of China
- Crypto Life, a day in the life of a Web3 project partner
- vlan间路由+静态路由+NAT(PAT+静态NAT)综合实验
- 直播预告 | KDD2022博士论文奖冠亚军对话
- Refuse to work overtime, a productivity tool set developed by programmers
猜你喜欢
随机推荐
To write good test cases, you must first learn test design
Drools规则属性,高级语法
[Map and Set] LeetCode & Niu Ke exercise
医疗影像领域AI软件开发流程
cudaMemcpy学习笔记
曼城推出可检测情绪的智能围巾,把球迷给整迷惑了
MySQL installation tutorial (detailed, package teaching package~)
Introduction and use of Drools WorkBench
Maximum monthly salary of 20K?The average salary is nearly 10,000... What is the experience of working in a Huawei subsidiary?
221. Largest Square
multiplayer-hlap 包有问题,无法升级的解决方案
Crawler text data cleaning
如何在 go 程序中暴露 Prometheus 指标
MySql installation and configuration super detailed tutorial and simple method of building database and table
Project development software directory structure specification
软件测试基础接口测试-入门Jmeter,你要注意这些事
Coldfusion file read holes (CVE - 2010-2861)
leetcode-952: Calculate max component size by common factor
User interaction + formatted output
The effective square of the test (one question of the day 7/29)









