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,而在源碼中沒有發現對於線程安全的處理,那么它應該也是非線程安全的。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM