Java 8 提供了一种新的字符串操作方式 StringJoiner ,相较上文介绍的字符串拼接10种方法, StringJoiner 是更为高级一些的用法了。
import java.util.StringJoiner; public class Test { public static void main(String[] args) { StringJoiner joiner; } }
StringJoiner 的操作和其他字符串类型不同,它的包来自于 java.util.StringJoiner 。
根据常规,通常 java.util 包下的内容可以理解为一个工具类。
通过 IDEA 分析,我们可以看到在这个类中提供的如下方法操作。
StringJoiner 的用法
接下来,我们就通过测试类的操作,来详解 StringJoiner 的用法。
先来创建一个测试类,示例代码:
public class Test { public static void main(String[] args) { StringJoiner stringJoiner = new StringJoiner("Hello"); stringJoiner.add("World"); stringJoiner.add("架构师面试"); System.out.println(stringJoiner.toString()); StringJoiner stringJoiner1 = new StringJoiner(":","[","]"); stringJoiner1.add("Hello").add("World").add("字符串操作"); System.out.println(stringJoiner1.toString()); } }
结果:
在 StringJoiner 类中,提供了两个构造函数,有 5 个公有的方法。其中,add 方法、toString 方法是使用最多的两种方法。
接下来,我们来了解下 add 方法的实现原理。
add 原理
我们来看 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; }
可见,add() 方法使用的是 StringBuilder 来进行字符串操作,并且使用 StringJoiner 和直接使用 StringBuilder 是一样的。
但是,为什么还要新增加这样一个类操作?
StringJoiner 分析
如果要将一个数组中的所有对象、拼接成一个大的字符串对象,应该怎样实现拼接?
第1种方法,采用循环数组对象、使用 StringBuilder 来进行拼接。
StringBuilder builder = new StringBuilder(); if (!list.isEmpty()) { builder.append(list.get(0)); for (int i = 1, n = list.size(); i < n; i++) { builder.append(",").append(list.get(i)); } } builder.toString();
第2种方法,使用 Java8 中提供的 lambda 表达式来进行拼接。
list.stream().reduce(new StringBuilder(), (sb, s) -> sb.append(s).append(','), StringBuilder::append).toString();
第3种方法,在循环中使用 + 的方式来进行拼接(不推荐)。
以认上3种方法,都能实现上面说的拼接,但由于涉及到循环,整体的效率都不是太高。
有没有可以提高效率的、更好的选择呢?
Java 8 中提供的字符串操作方式 StringJoiner ,就能在实现拼接的同时提高效率。
首先,我们来分析一个类 Collectors 。
java.util.stream.Collectors 可以实现各种有用的缩减操作的 Collector 。例如:将元素累积到集合中,根据各种标准汇总元素等。
通过这个类中的 joining() 方法:
public static Collector<CharSequence, ?, String> joining() { return new CollectorImpl<CharSequence, StringBuilder, String>( StringBuilder::new, StringBuilder::append, (r1, r2) -> { r1.append(r2); return r1; }, StringBuilder::toString, CH_NOID); } 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); }
将这个方法与 stream() 方法进行结合,也就是在 Java8 中提供的一些高级用法。
list.stream().collect(Collectors.joining(":"))
可见,在 joining() 方法中,既使用了 StringBuilder ,又使用了 StringJoiner ,来提高效率。
总结
本文主要介绍了Java 8 中的StringJoiner 的高级用法,以及几种方法的使用比较。
在实际研发中,还是要围绕提升开发效率为目的的,针对不同的场景、选择合适的方法。