Java1.8中StringJoiner的使用及源码详析

 更新时间:2018年08月09日 08:38:51   作者:GoldArowana  
在看String类时,看到有使用StringJoiner类,所以顺便看了下StringJoiner类,下面这篇文章主要给大家介绍了关于Java 1.8中StringJoiner的使用及源码分析的相关资料,需要的朋友可以参考借鉴,下面来一起看看吧

前言

StringJoiner是Java里1.8新增的类,主要是帮助我们把一个列表拼接字符串, 或许有一部分人没有接触过. 所以本文将从使用例子入手, 分析StringJoiner的源码.

基本好的同学, 其实只要把这段例子自己运行一下, 自己看看源码就可以了.因为我觉得这个类挺简单的. 没必要看我下面的废话....

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());
 }
}

输出结果如下:

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

上面的例子看懂的同学, 其实没必要往下看下去了....下面的几个例子就当是我自己做了个总结吧.

例1

public class StringJoinerTest2 {
 public static void main(String[] args) {
 StringJoiner joiner = new StringJoiner("--", "[[[_ ", "_]]]");
 System.out.println(joiner.toString());
 System.out.println(joiner.length());
 }
}

输出结果如下:

这个构造器要传入三个参数. 第一个是`分隔符` , 第二个是`前缀` , 第三个是 `后缀`. 现在不明白也没有关系, 下面待会儿会详细介绍.

咱们先把这个构造器对应的源码看了吧:

先是判断非空. 然后就开始赋值了. emptyValue被赋值为了prefix+suffix . 这段代码就是这么简单... 其中:

1. prefix 是前缀. (待会儿再讲)

2. delimiter 是分隔符 (待会儿再讲)

3. suffix 是后缀 (待会儿再讲)

4. emptyValue是本类的`空值`. 空值准确来说应该是null, 但StringJoiner类把emptyValue来当空值来处理. (马上就讲)

构造器看完了, 咱们再看看toString方法:

因为目前的代码里, 没有对value进行过赋值操作, 所以value肯定是null. 所以会执行第一个if.

也就是说真正的值value为空的时候, 就会返回本类默认的空值emptyValue. (大家有没有现在应该知道emptyValue的作用了吧)

toString就先分析这一小段if, 剩下的后面再讲. 接下来咱们看看length()方法:

value非空的时候, 长度就是value的长度+后缀的长度.(前缀呢? 前缀去哪儿了? 为什么不单独再加上前缀的长度呢? 带着这个疑惑往下看) .

value为空的时候, 长度就是emptyValue的长度.

例2

咱们往StringJoiner添加"1"

public class StringJoinerTest2 {
 public static void main(String[] args) {
 StringJoiner joiner = new StringJoiner("--", "[[[_", "_]]]");
 joiner.add("1");
 System.out.println("toString: " + joiner.toString());
 System.out.println("length: " + joiner.length());
 }
}

输出结果如下:

这个时候, 或许大家对`前缀` `后缀` 有些理解了吧. (还没理解也无所谓, 往下看)

咱们看看add方法的源码吧:

通过append方法, 将咱们传入的"1"添加到了末尾. 那么prepareBuilder()方法返回的是什么呢?看看源码吧:

咱们调用add("1")的时候, value为空. 所以会执行else语句. 在这里新实例化了一个StringBuilder. 然后StringBuilder先追加了`前缀`. (if语句先不讲, 等执行到了再讲)

所以此时prepareBuilder方法返回的value实际上就是前缀: "[[[_"

回到add方法, 刚才咱们说了add方法即时在prepareBuilder返回的值后面追加了"1"而已.

所以执行完add方法之后, value就等于 "[[[_1" 所以value里就已经包含了前缀了. 所以length方法里"为什么不单独再计算前缀的长度呢?" 因为value里面就已经包含前缀了.

咱们再看看toString方法:

这次value非空. 所以执行这里else语句:

如果suffix等于空字符串, 那么就返回value.

如果suffix不等于空字符串, 那么就返回value+后缀.

再看看length()方法:

value不为空, 所以返回的值是 value的长度+后缀的长度.

例3

public class StringJoinerTest2 {
 public static void main(String[] args) {
  StringJoiner joiner = new StringJoiner("--", "[[[_", "_]]]");
  joiner.add("1");
  joiner.add("2");
  joiner.add("3");
  joiner.add("4");
  System.out.println("toString: " + joiner.toString());
  System.out.println("length: " + joiner.length());
 }
}

输出结果如下:

add("1")和上一小节的执行流程一样. 这回看看add("2");的执行流程吧:

由于前面add("1")执行完了, 所以导致value已经不是null了. 所以这里会执行prepareBuilder方法里的if语句. 在value后直接追加一个delimiter分隔符. 然后返回这个value.

然后再add方法里, 把"2"追加到value后面.

例4

咱们发现add方法最后返回的是this.所以上面一小节的示例代码可以写成这样:

public class StringJoinerTest2 {
 public static void main(String[] args) {
  StringJoiner joiner = new StringJoiner("--", "[[[_", "_]]]");
  joiner.add("1").add("2").add("3").add("4");
  System.out.println("toString: " + joiner.toString());
  System.out.println("length: " + joiner.length());
 }
}

例5

StringJoiner还有一个构造器, 只需传入分隔符:

public class StringJoinerTest2 {
 public static void main(String[] args) {
  StringJoiner joiner2 = new StringJoiner("...");
  System.out.println("toString: " + joiner2.toString());
  System.out.println("length: " + joiner2.length());
  System.out.println("**************************************");
  joiner2.add("a");
  joiner2.add("b");
  joiner2.add("c");
  System.out.println("toString: " + joiner2.toString());
  System.out.println("length: " + joiner2.length());
 }
}

输出结果如下:

构造器源码如下:

就是只指定了分割符, 把前缀和后缀都指定为了空字符串.

例6

接下来咱们看看merge方法

public class StringJoinerTest2 {
 public static void main(String[] args) {
  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());
 }
}

输出结果如下:

merge的源代码如下:

咱们看到了用append方法进行了字符串追加. (append的时候刨除去了other.value 的前缀).

总结

1. prepareBuilder方法在value为空的时候, 给value加上前缀.

2. prepareBuilder方法在value非空的时候, 给value加上分隔符.

3. 很多方法都不能传入null为参数. 因为用Objects.requireNonNul方法限定了.

4. 前缀是包含在value里的. 而后缀部分是toString的时候才会被临时添加到value里.

好了,以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对脚本之家的支持。

相关文章

  • SpringBoot常见错误图文总结

    SpringBoot常见错误图文总结

    最近在使用idea+Springboot开发项目中遇到一些问题,这篇文章主要给大家介绍了关于SpringBoot常见错误总结的相关资料,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
    2023-06-06
  • Java虚拟机JVM优化实战的过程全记录

    Java虚拟机JVM优化实战的过程全记录

    有人说Java之所以能够崛起,JVM功不可没。Java虚拟机最初服务于让Java语言凌驾于平台之上,实现“编写一次,到处运行”,那么下面这篇文章主要给大家分享了个关于Java虚拟机JVM优化实战的过程全记录,需要的朋友可以参考借鉴,下面来一起看看吧。
    2017-08-08
  • Spring MVC拦截器的基本使用方法

    Spring MVC拦截器的基本使用方法

    这篇文章主要给大家介绍了关于Spring MVC拦截器的基本使用方法,文中通过示例代码介绍的非常详细,对大家学习或者使用Spring MVC具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
    2019-07-07
  • 详解Java接口签名(Signature)实现方案

    详解Java接口签名(Signature)实现方案

    这篇文章主要介绍了Java接口签名(Signature)实现方案 ,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-01-01
  • Java作用域、访问修饰符详解

    Java作用域、访问修饰符详解

    文章详细解释了Java中的作用域和访问修饰符,包括变量和方法的作用域,以及四种访问修饰符(public、protected、默认、private)的使用规则和可见性范围
    2025-02-02
  • Java语言ReadWriteLock特性实例测试

    Java语言ReadWriteLock特性实例测试

    这篇文章主要介绍了Java语言ReadWriteLock特性实例测试,分享了相关代码示例,小编觉得还是挺不错的,具有一定借鉴价值,需要的朋友可以参考下
    2018-02-02
  • Java Unsafe创建对象的方法实现

    Java Unsafe创建对象的方法实现

    Java中使用Unsafe实例化对象是一项十分有趣而且强大的功能,本文主要介绍了Java Unsafe创建对象的方法实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-07-07
  • 仅用5分钟极速入门Dubbo使用教程

    仅用5分钟极速入门Dubbo使用教程

    今天给大家介绍一款高性能、透明的远程过程调用框架dubbo,通过本文学习可以快速掌握Dubbo知识,感兴趣的朋友跟随小编一起看看吧
    2021-06-06
  • Maven中的SnapShot版本和正式版本的区别

    Maven中的SnapShot版本和正式版本的区别

    在Nexus仓库中,一个仓库一般分为public(Release)仓和SNAPSHOT仓,本文详细的介绍了SnapShot版本和正式版本的区别,感兴趣的可以了解一下
    2021-06-06
  • SpringBoot+Redis实现查找附近用户的示例代码

    SpringBoot+Redis实现查找附近用户的示例代码

    SpringDataRedis提供了十分简单的地理位置定位的功能,本文主要介绍了SpringBoot+Redis实现查找附近用户的示例代码,具有一定的参考价值,感兴趣的可以了解一下
    2024-02-02

最新评论