• Java8之StringJoiner


    中午躺在床上,闲来无事草草看了一眼微信,无意间发现了一篇技术文章,讲的是StringJoiner的运用。

    当时第一反应就是这玩意大概又是java8以上版本新出的东西吧?细看发现并不是,居然是java8中存在的一个用于构建字符串的类。以前居然完全没听说过... ...惊叹之余,决定必须学一波。

    由于这个类比较简单,所以可以直接看着源码学习。

    private final String prefix;
    private final String delimiter;
    private final String suffix;
    private StringBuilder value;
    private String emptyValue;

    首先来看一下类中存在的五个成员变量,依次为前缀、分隔符、后缀、用于处理字符串的StringBuilder、和空值(是这么翻译吧?)

    看到这里大概就反应过来了,原来这个类是对于StringBuilder的再次封装。

    然后,会发现紧随其后的是两个构造方法

    public StringJoiner(CharSequence delimiter) {
            this(delimiter, "", "");
    }
    
    public StringJoiner(CharSequence delimiter,
                            CharSequence prefix,
                            CharSequence suffix) {
            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");
            // make defensive copies of arguments
            this.prefix = prefix.toString();
            this.delimiter = delimiter.toString();
            this.suffix = suffix.toString();
            this.emptyValue = this.prefix + this.suffix;
    }

    可见第一个构造器内部调用了第二个构造器,将第二个构造器的两个参数设为默认值“”,第二个构造器实际上就是需要使用者传入分隔符、前缀、后缀,并且空值被设为前缀加后缀。

    看到这里大概可以猜测到空值的作用就是在StringJoiner没有添加任何字符串的情况下,得到的最终值。

    public StringJoiner setEmptyValue(CharSequence emptyValue) {
            this.emptyValue = Objects.requireNonNull(emptyValue,
                "The empty value must not be null").toString();
            return this;
    }

    设置空值,这个方法没什么好说的

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

    value是StringBuilder对象,如果为null,那么直接返回空值。

    如果后缀为“”,直接返回value的toString(),如果后缀不为“”,那么需要将后缀拼接好然后一并返回。

    public StringJoiner add(CharSequence newElement) {
            prepareBuilder().append(newElement);
            return this;
    }

    然后是比较常用的add方法,内部调用了prepareBuilder()方法,最后返回对象本身,也就实现了链式调用。

    private StringBuilder prepareBuilder() {
            if (value != null) {
                value.append(delimiter);
            } else {
                value = new StringBuilder().append(prefix);
            }
            return value;
        }

    prepareBuilder()方法也比较简单,如果没有StringBuilder对象,那么就创建一个然后添加前缀,如果有,则添加分隔符,返回StringBuilder对象本身。

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

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

    这两个方法好像也没啥好说的... ...

    既然StringJoiner实际上使用的仍然是StringBuilder,而在源码中没有发现对于线程安全的处理,那么它应该也是非线程安全的。

  • 相关阅读:
    DispatcherServlet
    上转型对象
    Javascript闭包(Closure)
    跨域
    dict
    Python 函数参数传递方式
    协同过滤
    白话 动态规划 第一节 初识动态规划
    Spring@Autowired注解与自动装配
    protected
  • 原文地址:https://www.cnblogs.com/wxdmw/p/13999557.html
Copyright © 2020-2023  润新知