StringJoiner 源碼閱讀

StringJoiner

  • 屬性說明
/**
 *  StringJoiner 使用指定的分割符將多個字符串進行拼接,並可指定前綴和後綴
 *
 * @see java.util.stream.Collectors#joining(CharSequence)
 * @see java.util.stream.Collectors#joining(CharSequence, CharSequence, CharSequence)
 * @since  1.8
 */
public final class StringJoiner {
    /**
     *  前綴
     */
    private final String prefix;

    /**
     *  分割符
     */
    private final String delimiter;

    /**
     *  後綴
     */
    private final String suffix;

    /** 持續添加的字符串數組 */
    private String[] elts;

    /** 已添加的字符串個數 */
    private int size;

    /** 所有字符串的總長度,包括前綴和後綴 */
    private int len;

    /**
     *  空值
     *
     * When null, prefix + suffix is used as the empty value.
     */
    private String emptyValue;
  • 實例化
    /**
     *  創建分割符爲 delimiter,前綴和後綴都爲 "" 的 StringJoiner 對象
     *
     * @param  delimiter    分割符
     */
    public StringJoiner(CharSequence delimiter) {
        this(delimiter, "", "");
    }

    /**
     *  創建指定分割符、前綴、後綴的 StringJoiner
     *
     * @param  delimiter    用於連接字符串的分隔符
     * @param  prefix   前綴字符序列
     * @param  suffix   後綴字符序列
     */
    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();
    }
  • 追加字符串
    /**
     *  追加字符串 newElement 到此 StringJoiner 中
     *
     * @param  newElement   追加的新元素
     */
    public StringJoiner add(CharSequence newElement) {
        final String elt = String.valueOf(newElement);
        // 1)創建長度爲 8 的初始緩衝區
        if (elts == null) {
            elts = new String[8];
        } else {
            // 如果已滿,則執行雙倍擴容
            if (size == elts.length) {
                elts = Arrays.copyOf(elts, 2 * size);
            }
            // 記錄總字符數
            len += delimiter.length();
        }
        // 記錄總字符數
        len += elt.length();
        // 寫入目標元素
        elts[size++] = elt;
        return this;
    }
  • 返回此 StringJoiner 的字符串表示
    /**
     *  返回此 StringJoiner 的字符串表示
     */
    @Override
    public String toString() {
        final String[] elts = this.elts;
        // 1)嘗試返回空值
        if (elts == null && emptyValue != null) {
            return emptyValue;
        }
        final int size = this.size;
        final int addLen = prefix.length() + suffix.length();
        // 如果未指定前綴和後綴
        if (addLen == 0) {
            // 完成字符串拼接
            compactElts();
            return size == 0 ? "" : elts[0];
        }
        final String delimiter = this.delimiter;
        final char[] chars = new char[len + addLen];
        int k = getChars(prefix, chars, 0);
        if (size > 0) {
            k += getChars(elts[0], chars, k);
            for (int i = 1; i < size; i++) {
                k += getChars(delimiter, chars, k);
                k += getChars(elts[i], chars, k);
            }
        }
        k += getChars(suffix, chars, k);
        return new String(chars);
    }

    private void compactElts() {
        // 完成字符串拼接
        if (size > 1) {
            final char[] chars = new char[len];
            // 寫入第一個字符串
            int i = 1, k = getChars(elts[0], chars, 0);
            do {
                // 寫入分割符
                k += getChars(delimiter, chars, k);
                // 寫入後一個字符串
                k += getChars(elts[i], chars, k);
                elts[i] = null;
            } while (++i < size);
            size = 1;
            elts[0] = new String(chars);
        }
    }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章