还只会StringBuilder?StringJoiner真香

关于StringJoiner

    • 1.介绍
    • 2.源码
      • 2.1 属性
      • 2.2 方法
    • 3 举例
      • StringJoiner做法
      • 3.1 只含间隔符
      • 3.2 含间隔符和前后缀
      • 3.3 merge合并两个joiner
      • 3.4 stringJoiner.setEmptyValue("xxx");
      • 3.5 综合举例+length()方法

1.介绍

  • 在JDK1.8之后,提供了一个StringJoiner类用来进行字符串拼接处理,其可以在初始化的时候指定分隔符和前缀后缀;

  • 实现逻辑和StringBuilder基本是一样的逻辑,另外加入了前缀后缀、多了一个merge的功能;

  • 作用:处理字符串拼接的工具类;

  • 好处:比StringBuilder和StringBuffer更加方便、便捷、优雅;

2.源码

源码:
package java.util;

public final class StringJoiner {
    
--属性
    private final String prefix;//前缀
    private final String delimiter;//间隔符
    private final String suffix;//后缀
    private StringBuilder value;//值
    private String emptyValue;//空值
--只含间隔符的构造
    public StringJoiner(CharSequence delimiter) {
        this(delimiter, "", "");//默认前缀和后缀为"",重载调用
    }
--含间隔符以及前后缀的构造
    public StringJoiner(CharSequence delimiter,
                        CharSequence prefix,
                        CharSequence suffix) {
        //间隔符,前缀和后缀判断是否为null,null将抛出异常
        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"); 
        // 成员变量赋值
        this.prefix = prefix.toString();
        this.delimiter = delimiter.toString();
        this.suffix = suffix.toString();
        this.emptyValue = this.prefix + this.suffix;//空值被设置为只有前后缀
    }
	//设置空值,检查是否为null
    public StringJoiner setEmptyValue(CharSequence emptyValue) {
        this.emptyValue = Objects.requireNonNull(emptyValue,
            "The empty value must not be null").toString();
        return this;
    }
--toString()方法
    @Override
    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;
            }
        }
    }
--add元素开始进行初始化,先添加前缀,有了之后每次先添加间隔符,StringBuilder后续append字符串
    public StringJoiner add(CharSequence newElement) {
        prepareBuilder().append(newElement);
        return this;
    }
--合并StringJoiner,注意后面StringJoiner 的前缀就不要了,后面的appen进来
    public StringJoiner merge(StringJoiner other) {
        Objects.requireNonNull(other);
        if (other.value != null) {
            final int length = other.value.length();
            // lock the length so that we can seize the data to be appended
            // before initiate copying to avoid interference, especially when
            // merge 'this'
            StringBuilder builder = prepareBuilder();
            builder.append(other.value, other.prefix.length(), length);
        }
        return this;
    }
	//初始化,先添加前缀,有了之后每次先添加间隔符
    private StringBuilder prepareBuilder() {
        if (value != null) {
            value.append(delimiter);
        } else {
            value = new StringBuilder().append(prefix);
        }
        return value;
    }
--拿长度 拿的是加了间隔符和前后缀后的长度,若无元素拼接则不算间隔符长度(详情见下面分析)
    public int length() {
        // Remember that we never actually append the suffix unless we return
        // the full (present) value or some sub-string or length of it, so that
        // we can add on more if we need to.
        //不忘添加后缀的长度
        return (value != null ? value.length() + suffix.length() :
                emptyValue.length());
    }
}

2.1 属性

  • prefix:拼接后的字符串前缀
  • delimiter:拼接时的字符串分隔符
  • suffix:拼接后的字符串后缀
  • value:拼接后的值
  • emptyValue:空值的情况,value为null时返回

2.2 方法

  • setEmptyValue():设置空值
  • toString():转换成String
  • add():添加字符串
  • merge():从另一个StringJoiner合并
  • length():长度(包括前后缀)

3 举例

  • 举例:把一个字符串集合使用 “ ,”(逗号)分隔开;
  • 先看之前的StringBuilder做法
# StringBuilder做法
String a = "a", b = "b", c = "c";
List<String> list = new ArrayList<>();
list.add(a);
list.add(b);
list.add(c);
String s=""
StringBuilder builder = new StringBuilder();
list.forEach(s -> builder.append(s).append(","));
// 最后在处理掉多余的","
System.out.println(builder.toString().substring(0, builder.length() - 1));
// 输出结果:a,b,c

StringJoiner做法

参数不同,使用不同(调用的构造函数不同,呈现的用法不同)

3.1 只含间隔符

StringJoiner stringJoiner=new StringJoiner(",")把字符串根据“,”进行拼接

stringJoiner.add("a");
stringJoiner.add("b");
stringJoiner.add("c");
System.out.println(stringJoiner);//a,b,c

3.2 含间隔符和前后缀

StringJoiner stringJoiner=new StringJoiner(",","[","]"); 字符串 根据"," 拼接,并且用 "[" 和 "]" 包住首尾

stringJoiner.add("a");
stringJoiner.add("b");
stringJoiner.add("c");
System.out.println(stringJoiner);//[a,b,c]

3.3 merge合并两个joiner

merge的思路是用当前的stringJoiner去append other的value,merge时去掉前后缀只进行value的拼接;
merger后加上前后缀,比如A merge B,那么最后就加上A的前后缀,且进行value拼接的时候连接A和B使用的是A的拼接符

StringJoiner stringJoiner1=new StringJoiner(":","[","]");
StringJoiner stringJoiner2=new StringJoiner(".","(",")");
stringJoiner1.add("a").add("b").add("c");
stringJoiner2.add("d").add("e").add("f");
System.out.println(stringJoiner1);//[a:b:c]
System.out.println(stringJoiner2);//(d.e.f)
stringJoiner1.merge(stringJoiner2);//[a:b:c:d.e.f]

3.4 stringJoiner.setEmptyValue(“xxx”);

设置空值,目的我们在源码中可以看出,在无拼接元素的时候也就是valu为空时,返回的是这个emptyValue的值/长度

3.5 综合举例+length()方法

StringJoiner stringJoiner1=new StringJoiner(":","[","]");
StringJoiner stringJoiner3=new StringJoiner("*");
--无元素拼接 含前后缀
System.out.println(stringJoiner1.length());//2(前后缀长度)
System.out.println(stringJoiner1);//[]
--无元素拼接 只含间隔符
System.out.println(stringJoiner3.length());//0(无元素拼接时,间隔符不算,前后缀算)
System.out.println(stringJoiner3);//空(什么也没有)
--加上元素拼接 
stringJoiner1.add("a").add("b");
System.out.println(stringJoiner1.length());//5
System.out.println(stringJoiner1);//[a:b]
--设置emptyValue (此时stringjoiner3无元素拼接,再设置emptyValue后返回的是empty的长度和值)
stringJoiner3.setEmptyValue("123456");
System.out.println(stringJoiner3.length());//6
System.out.println(stringJoiner3);//123456

你可能感兴趣的:(JAVA--基础学习,python,java,算法,数据结构,spring,boot)