面试题
在之前的内容中我们介绍了字符串。同时,也介绍了字符串的拼接操作,并且分析了几种字符串拼接方式的原理。其实在JAVA8中还提供了一种新的字符串操作方式。就是今天我们要来深入讨论的stringJoiner。
import java.util.StringJoiner;public class Test {public static void main(String[] args) {StringJoiner joiner;
与其他的字符串操作不同的是,这个类的包是来自于java.util.StringJoiner,通过IDEA分析可以看到在这个类中提供了如下的一些方法操作。根据惯例来自于java.util包下的内容一般可以理解为一个工具类。这也就是为什么这个类与其他字符串类型不同的原因。
用法讲解
首先我们先来创建一个测试类,通过测试类的操作来讲解这个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;
会看到这里使用的也是StringBuilder来进行字符串操作。分析源码可以知道,其实使用StringJoiner和直接使用StringBuilder是一样的。那么为什么还要多此一举地实现开发这样一个类操作呢?
StringJoiner分析
如果在实际开发中遇到这样一个操作,我们要将一个数组中的所有对象拼接成一个大的字符串对象,那么我们应该如何去操作呢?
结合之前的分析,我们可以循环数组对象,并且使用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();
当然我们还可以使用Java8中提供lambda表达式来进行操作。代码如下。其实操作和循环操作实现的方式是一样的。
list.stream().reduce(new StringBuilder(), (sb, s) -> sb.append(s).append(','), StringBuilder::append).toString();
还可以使用我们最不推荐的方式在循环中使用+的方式来进行拼接。
这些操作都可以完成上面的内容,但是由于涉及到循环,所以说整体的效率都不是太高。
为了提升操作效率StringJoiner类就出现了。首先我们来分析一个类Collectors,java.util.stream.Collectors实现各种有用的缩减操作的Collector的实现,例如将元素累积到集合中,根据各种标准汇总元素等。通过这个类中的joining()方法代码如下。
public static Collector joining() {return new CollectorImpl(StringBuilder::new, StringBuilder::append,(r1, r2) -> { r1.append(r2); return r1; },StringBuilder::toString, CH_NOID);public static Collector 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。最终的效果都是实现高效。
总结
这篇文章主要介绍了Java8中对于字符串操作的一些高级用法,但是尽管是高级用法也只是以提升开发效率为目的,这些高级用法都可以使用基本用法来代替,只是在日常的开发中为了提升开发效率。我们会采用一些高级用法,但是想要理解这些高级用法还要基础知识做支持,希望大家多多关注,后续会为大家带来更多的干货内容。