欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

都知道StringBuilder、StringBuffer,可知StringJoiner?

程序员文章站 2022-10-03 10:53:17
今早看String源码的时候发现 join()方法中有StringJoiner,出于好奇把该文件从头到尾看了一遍,现介绍下StringJoiner。...

  今早看String源码的时候发现 join()方法中有StringJoiner,出于好奇把该文件从头到尾看了一遍,现介绍下StringJoiner。

一、应用环境

 从源码来看该文件适用环境 JDK8 ,如图:
都知道StringBuilder、StringBuffer,可知StringJoiner?

二、属性及方法

1. 属性

1.1 prefix

  字符串拼接的前缀,私有并且是 一旦赋值不可更改的String类型变量。
都知道StringBuilder、StringBuffer,可知StringJoiner?

1.2 suffix

  字符串拼接后缀,私有并且一旦赋值不可更改的String类型变量。
都知道StringBuilder、StringBuffer,可知StringJoiner?

1.3 delimiter

  字符串拼接时,内容之间的分隔符,私有并且一旦赋值不可更改的String类型变量。
都知道StringBuilder、StringBuffer,可知StringJoiner?

1.4 value

    私有的StringBuilder实例。StringBuilder—在任何时候,由前缀构造的字符,添加的元素由分隔符分隔,但没有后缀,因此我们可以更容易地添加元素,而不必每次都修改后缀。
都知道StringBuilder、StringBuffer,可知StringJoiner?

1.5 emptyValue

    私有String类型变量。默认情况下,toString()返回的由前缀+后缀组成的字符串,或值的属性,当没有添加元素时,即当它为空时。这可能会被用户覆盖为包括空字符串在内的其他值。
都知道StringBuilder、StringBuffer,可知StringJoiner?

2.方法

2.1 构造方法

  该类中没有无参构造,仅有有参构造,分别是单个参数构造和三个参数构造。

2.1.1 单参构造

  如下图所知,单参构造方法仅传 delimiter(分隔符) 即可,在其方法体中调用的是多参构造方法,并且 prefixsuffix 都设置为空字符。
(注:这里的空字符和null是有区别的,在多参构造方法中会捕捉null并抛出异常。)
都知道StringBuilder、StringBuffer,可知StringJoiner?

2.1.2 多参构造

该类中多参构造指的仅仅是含有三个参数的构造方法,如下图所示。
都知道StringBuilder、StringBuffer,可知StringJoiner?
    该构造方法在构建StringJoiner对象时可以设置 delimiter、prefix、suffix 变量,但是绝对不能传 null ,否则会抛出对应的 NullPointerException ,如下图所示:

  // 示例1 delimiter设置 null
  StringJoiner sj = new StringJoiner(null,"sjpre","sjsuf");

都知道StringBuilder、StringBuffer,可知StringJoiner?

  // 示例2 prefix 设置 null
  StringJoiner sj = new StringJoiner(",",null,"sjsuf");

都知道StringBuilder、StringBuffer,可知StringJoiner?

  // 示例3 suffix 设置 null
  StringJoiner sj1 = new StringJoiner(",","sjpre",null);

都知道StringBuilder、StringBuffer,可知StringJoiner?

2.2 setEmptyValue

    使用StringJioner时,并且还有没有添加元素时(当它为空时)要使用的 emptyValue 参数副本。注意,一旦调用了add方法,即使添加的元素与空的 String 对应,StringJoiner也不再认为是空的。如果调用时传 null 会抛出 NullPointerException 异常。

  // 示例 调用setEmptyValue方法时传入null
  StringJoiner sj1 = new StringJoiner(",","sjpre","sjsuf");
  sj1.setEmptyValue(null);

都知道StringBuilder、StringBuffer,可知StringJoiner?

2.3 toString

    该方法是重写Object的toString方法。返回由 prefix 、delimiter、suffix 组成的当前值,如果没有添加任何元素,则将返回 prefix + suffixemptyValue 字符串。

2.3.1 返回 prefix 、delimiter、suffix 组成的字符串

  // 示例 构建含有prefix、suffix、delimiter 的StringJoiner实例
  StringJoiner sj1 = new StringJoiner(",","sjpre_","_sjsuf");
  // 使用链式结构添加数据,验证分隔符是否有效
  sj1.add("使用StringJoiner").add("探究StringJoiner神秘之处");
  // 输出 实例sj1的内容
  System.out.println(sj1.toString());

都知道StringBuilder、StringBuffer,可知StringJoiner?

2.3.2 返回 prefix + suffix 组成的字符串

  // 示例 当实例sj1不添加任何数据,输出时仅包含prefix+suffix
  StringJoiner sj1 = new StringJoiner(",","sjpre_","_sjsuf");
  System.out.println(sj1.toString());

都知道StringBuilder、StringBuffer,可知StringJoiner?
注意:
    该示例返回的结果看似是prefix+suffix的值,实则是 emptyValue 的值。因为在多参构造方法里 执行了 this.emptyValue = this.prefix + this.suffix;代码,最终将prefix+suffix的值赋给emptyValue 变量。并且根据StringJoiner.toString源码可知,如果 value实例为null返回emptyValue 。此处没有单独设置 emptyValue ,所以直观感觉输出了prefix+suffix。

2.3.3 单独设置emptyValue ,并返回 emptyValue

  // 单独设置 setEmptyValue 的值,弥补上面示例缺陷
  StringJoiner sj1 = new StringJoiner(",","sjpre_","_sjsuf");
  sj1.setEmptyValue("没有添加任何值,这里是setemptyValue方法");
  System.out.println(sj1.toString());

都知道StringBuilder、StringBuffer,可知StringJoiner?

为什么出现这样的结果?直接上源码消除你的疑问。

都知道StringBuilder、StringBuffer,可知StringJoiner?
通过分析源码可以明白以上示例结果出现的原由。

2.4 prepareBuilder

    该方法是 StringJoiner 私用方法,在内部 add()merge() 方法逻辑中调用。当 StringBuilder 实例不为空时添加 delimiter(分隔符);为空时创建StringBuilder实例,然后添加 prefix 前缀,最后返回StringBuilder实例。
都知道StringBuilder、StringBuffer,可知StringJoiner?

2.5 add

    添加内容,调用的是 StringBuilder 的append()方法,并返回添加后的StringJoiner实例,可以使用链式结构添加数据。
都知道StringBuilder、StringBuffer,可知StringJoiner?

  StringJoiner sj1 = new StringJoiner(",","sjpre_","_sjsuf");
  sj1.add("添").add("加").add("内").add("容"); // 链式添加结构
  System.out.println(sj1.toString());

都知道StringBuilder、StringBuffer,可知StringJoiner?

2.6 merge

    将两个StringJoiner合并为一个StringJoiner实例,调用该方法时需要传输StringJoiner实例。如下图源码所示。
都知道StringBuilder、StringBuffer,可知StringJoiner?
    仅会合并传入的StringJoiner 实例的vlaue值,无论传入的StringJoiner实例是否含有 prefix和suffix,都不会合并。会保留调用merge方法实例的 prefix和suffix。还需要注意的是传入的StringJoiner实例不能为 null ,否则会抛出 NullPointerException 异常。

  // 创建第一个StringJoiner实例sjOne
  StringJoiner sjOne = new StringJoiner(",","sjpreOne_","_sjsufOne");
  // sjOne添加内容
  sjOne.add("测").add("试").add("StringJoinerOne");
  // 创建第一个StringJoiner实例sjTwo
  StringJoiner sjTwo = new StringJoiner("+","sjpreTwo_","_sjsufTwo");
  // sjTwo添加内容
  sjTwo.add(" DEMO").add("demo").add("StringJoinersTwo ");
  // sjOne调用merge方法与sjTwo实例合并,输出合并后的结果
  System.out.println(sjOne.merge(sjTwo).toString());

都知道StringBuilder、StringBuffer,可知StringJoiner?
    以上实例中,sjOne和sjTwo实例都含有 prefix、suffix、delimiter,sjOne调用merge方法与sjTwo合并,通过输出结果可以看出sjTwo实例的prefix和suffix没有合并,合并的只有sjTwo内部的StringBuilder实例value。

当传入null 时,会抛出NullPointerException异常。

  // 示例 调用merge传入null
  StringJoiner sjOne = new StringJoiner(",","sjpreOne_","_sjsufOne");
  sjOne.merge(null);

都知道StringBuilder、StringBuffer,可知StringJoiner?

2.7 length

    返回StringJoiner的长度。如果没有调用任何添加方法,将返回 prefix+suffix 长度或者 emptyValue 的长度。
都知道StringBuilder、StringBuffer,可知StringJoiner?

三、总结

  1. 该类适用在 JDK8+ 的环境上。
  2. 避免拼接字符串时,生硬处理分隔符的问题。注:分隔符 不可以传 null
  3. 合理的设置字符串前后缀,但不可以传 null
  4. 合并多个StringJoiner实例,合并时不能合并 null
  5. StringJoiner实例没有添加任何内容时,会输出emptyValue的值。
  6. StringJoiner底层使用的是StringBuilder,非线程安全。不适用并发场景,否则会出现ABA问题。

本文地址:https://blog.csdn.net/qq_38922576/article/details/109800830