StringJoiner

154 阅读2分钟

StringJoiner (Java Platform SE 8 )

StringJoiner用于构造由分隔符分隔的字符序列,并且可选地从提供的前缀开始并以提供的后缀结尾。

在此之前添加一些东西到StringJoiner ,其sj.toString()方法,默认情况下,返回prefix + suffix 。 但是,如果调用了setEmptyValue方法,则将返回提供的emptyValue 。 这可用于,例如,使用一组表示法来表示空集,即创建字符串时"{}" ,其中prefix"{"时, suffix"}"和什么已被添加到StringJoiner

package java.util;

public final class StringJoiner {
    // 字首
    private final String prefix;
    // 分隔符
    private final String delimiter;
    // 后缀
    private final String suffix;

    /*
     * StringBuilder值——任何时候,由*前缀构造的字符,添加的元素用分隔符分隔,但不带
     * 后缀,这样我们可以更方便的添加元素,而不必每次都跳动
     * 后缀。
     */
    private StringBuilder value;

    /*
     * 默认情况下,由toString() 返回的前缀 + 后缀组成的字符串,或 value 的属性,当尚未添加
     * 任何元素时,即为空时。这可能会被用户覆盖为一些其他值,包括空字符串。
     */
    private String emptyValue;

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

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

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

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

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

    //  生成新的 StringBuilder 准备生成器
    private StringBuilder prepareBuilder() {
        if (value != null) {
            value.append(delimiter);
        } else {
            value = new StringBuilder().append(prefix);
        }
        return value;
    }

    public int length() {
        // 请记住,除非我们返回完整(当前)值或它的某些子字符串或长度,
        // 否则我们从不实际附加后缀,以便我们可以在需要时添加更多。
        return (value != null ? value.length() + suffix.length() :
                emptyValue.length());
    }
}
public class Deom {

    public static void main(String[] args) {
        StringJoiner ps1 = new StringJoiner(":");
        ps1.add("xiaozeng");
        ps1.add("xiaohong");
        System.out.println(ps1);

        StringJoiner ps2 = new StringJoiner(":", "[", "]");
        ps2.add("xiaohei");
        ps2.add("xiaoming");
        ps2.add("xaiohuang");
        System.out.println(ps2);

        // ps1 后面加上 ps2
        System.out.println(ps1.merge(ps2));
    }
}

运行结果

xiaozeng:xiaohong
[xiaohei:xiaoming:xaiohuang]
xiaozeng:xiaohong:xiaohei:xiaoming:xaiohuang